home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 20 / CU Amiga Magazine's Super CD-ROM 20 (1998)(EMAP Images)(GB)[!][issue 1998-03].iso / CDsupport / HappyENV / Source / HappyENV-Handler.asm < prev    next >
Assembly Source File  |  1997-06-12  |  52KB  |  2,557 lines

  1. *************************
  2. *   HappyENV-Handler    *
  3. *     1.0 05.06.97    *
  4. *  (C) Martin Gierich    *
  5. *************************
  6.  
  7.  
  8. * Do not use this source code or parts of it in other programs !
  9. * See documentation about Copyright&Disclaimer.
  10. * Sorry about the not so well commented source.
  11.  
  12.  
  13. * Switches for options, enabled if label is defined,
  14. * disabled if semicolon is put in front of it.
  15.  
  16. ;DEBUG        = 1    ;allow debugging output via sushi (RawPutChar)
  17. ;VERBOSE    = 1    ;verbose debug output
  18. ;EXPAND        = 1
  19.  
  20.  
  21.     INCDIR    source:stripinc/
  22.     INCLUDE    exec/exec_lib.i
  23.     INCLUDE    dos/dos_lib.i
  24.     INCLUDE    dos/dosextens.i
  25.     INCLUDE    dos/filehandler.i
  26.     INCLUDE    dos/notify.i
  27.     INCLUDE    dos/rdargs.i
  28.     INCLUDE debug.i
  29.  
  30. * macro for calling OS routines
  31.  
  32. CALL    MACRO
  33.     jsr    _LVO\1(a6)
  34.     ENDM
  35.  
  36. * other macros
  37. * compare both operands and store minimum in the right one
  38. * third argument is label name
  39.  
  40. MIN    MACRO
  41.     cmp.l    \2,\1
  42.     bhs.s    .\3
  43.     move.l    \1,\2
  44. .\3    nop
  45.     ENDM
  46.  
  47. * miscellaneous definitions
  48.  
  49. LF        = 10
  50. mn_Node        = 0
  51. lib_Version    = 20
  52. _LVOToUpper    = -174
  53. _LVOEasyRequestArgs = -588
  54. DOS_TRUE    = -1
  55. DOS_FALSE    = 0
  56. MEMF_CLEAR    = $10000
  57. MAXPATH        = 120
  58. MAXNAME        = 32
  59. BLOCKSIZE    = 5000
  60.  
  61. * EasyRequest structure (Intuition)
  62.         RSRESET
  63. es_StructSize    RS.L    1
  64. es_Flags    RS.L    1
  65. es_Title    RS.L    1
  66. es_TextFormat    RS.L    1
  67. es_GadgetFormat    RS.L    1
  68. es_SIZEOF    RS.W    0
  69.  
  70.  
  71. * notify list node structure
  72.         RSRESET
  73. myn_Link    RS.L    1
  74. myn_Request    RS.L    1    ;notify-request
  75. myn_Key        RS.L    1    ;pointer to file
  76. myn_Name    RS.B    0    ;path/file name (dynamic)
  77.  
  78. * lock structure for Lock() and open files
  79.         RSRESET
  80. myl_Link    RS.L    1
  81. myl_Key        RS.L    1
  82. myl_Access    RS.L    1
  83. myl_Task    RS.L    1
  84. myl_Volume    RS.L    1
  85. myl_Pos        RS.L    1    ;position in file (read/write)
  86. myl_Data    RS.L    1    ;start of file data (read)
  87. myl_Start    RS.L    1    ;start of block list (write)
  88. myl_Block    RS.L    1    ;current block (write)
  89. myl_BlockPos    RS.L    1    ;position in current block (write)
  90. myl_Size    RS.L    1    ;size of file
  91. myl_Mode    RS.B    1    ;0=simple lock, -1=write, 1=read
  92. myl_Pad        RS.B    1
  93. myl_SIZEOF    RS.W    0
  94.  
  95. * structure for file or dir
  96.         RSRESET
  97. myf_Link    RS.L    1    ;next file/dir
  98. myf_Parent    RS.L    1    ;parent dir (root: 0)
  99. myf_First    RS.L    0    ;dir:  points to first entry
  100. myf_Size    RS.L    1    ;file: size of filedata
  101. myf_Type    RS.B    1    ;bit7: dir/file, 6:hidden, 5:copied,
  102.                 ;4:notify
  103. myf_Locks    RS.B    1    ;number of locks, -1=write lock
  104. myf_DataOffs    RS.B    1    ;offset to start of data
  105. myf_Name    RS.W    0    ;name (dynamic), then data
  106.  
  107. * private main structure
  108.         RSRESET
  109. CharTable    RS.B    256
  110. DosBase        RS.L    1
  111. IntuiBase    RS.L    1
  112. MyProcess    RS.L    1
  113. MyMsgPort    RS.L    1
  114. MyMemPool    RS.L    1
  115. MyDeviceNode    RS.L    1
  116. MyVolumeBPTR    RS.L    1
  117. NotifyList    RS.L    1
  118. Copyfrom    RS.L    1
  119. CopyfromLock    RS.L    1
  120. CopyfromPort    RS.L    1
  121. RootLock    RS.L    1
  122. StartDate    RS.B    ds_SIZEOF
  123. MyPacket    RS.B    sp_SIZEOF
  124. VolumeNode    RS.B    DevList_SIZEOF
  125. VolumeName    RS.B    MAXNAME
  126. NotifyPort    RS.B    MP_SIZE
  127. PacketPort    RS.B    MP_SIZE
  128. FileSize    RS.L    1
  129. TotalSize    RS.L    1
  130. NumLocks    RS.L    1
  131. Kickver        RS.W    1
  132. WriteProtected    RS.B    1
  133. NSignal        RS.B    1
  134. PSignal        RS.B    1
  135. Paddy1        RS.B    1
  136. RootDir        RS.B    myf_Name+8
  137. Paddy2        RS.B    3
  138. TempPath    RS.B    MAXPATH
  139. TempName    RS.B    MAXNAME
  140. ReqStruct    RS.B    es_SIZEOF
  141. FormatArgs    RS.L    2
  142. StupVolname    RS.L    1
  143. StupIcon    RS.B    1
  144. StupNocopy    RS.B    1
  145. StupNoreq    RS.B    1
  146. StupExpand    RS.B    1
  147. My_SIZEOF    RS.W    0
  148.  
  149. MyPkt        = MyPacket+sp_Pkt
  150.  
  151. *******************************************************
  152.  
  153. *******************************************************
  154.  
  155. * common register usage:
  156. * a4=DOSpacket
  157. * a5=private struct
  158. * a6=execbase
  159.  
  160. start:    movem.l    d2-d7/a2-a6,-(sp)    ;do some basic inits
  161.     move.l    4.w,a6
  162.     move.l    #My_SIZEOF,d0
  163.     move.l    #MEMF_CLEAR!1,d1
  164.     CALL    AllocMem
  165.     tst.l    d0
  166.     beq    exit1
  167.     move.l    d0,a5
  168.     DBUG1    txstart,a5
  169.     lea    dosname(pc),a1
  170.     moveq    #33,d0
  171.     CALL    OpenLibrary
  172.     move.l    d0,DosBase(a5)
  173.     beq    exit2
  174.     move.l    d0,a2
  175.     CALL    Forbid
  176.     move.l    dl_Root(a2),a0
  177.     lea    rn_Time(a0),a0
  178.     lea    StartDate(a5),a1
  179.     move.l    (a0)+,(a1)+
  180.     move.l    (a0)+,(a1)+
  181.     move.l    (a0),(a1)
  182.     CALL    Permit
  183.     move.w    lib_Version(a6),Kickver(a5)
  184.     sub.l    a1,a1
  185.     CALL    FindTask
  186.     move.l    d0,MyProcess(a5)
  187.     cmp.w    #36,Kickver(a5)
  188.     blo.s    .OS13
  189.     move.l    d0,a0
  190.     bset    #0,pr_Flags+3(a0)
  191. .OS13    add.l    #pr_MsgPort,d0
  192.     move.l    d0,MyMsgPort(a5)
  193. ;    clr.b    RootDir+myf_Type(a5)
  194.     cmp.w    #39,Kickver(a5)
  195.     blo.s    .OS20
  196.     moveq    #1,d0
  197.     move.l    #5000,d1
  198.     move.l    #2000,d2
  199.     CALL    CreatePool
  200.     move.l    d0,MyMemPool(a5)
  201.  
  202. .OS20    move.l    MyMsgPort(a5),a2    ;process startup message
  203.     bsr    GetPacket
  204.     move.l    d0,a4
  205.     move.l    dp_Arg3(a4),d0
  206.     lsl.l    #2,d0
  207.     move.l    d0,MyDeviceNode(a5)
  208.     move.l    d0,a0
  209.     move.l    MyMsgPort(a5),dn_Task(a0)
  210.     clr.l    dn_SegList(a0)
  211.     move.l    dn_Name(a0),a0
  212.     lea    RootDir+myf_Name(a5),a1
  213.     moveq    #6,d0
  214.     bsr    CopyBSTR2Char
  215.     moveq    #DOS_TRUE,d0
  216.     move.l    d0,dp_Res1(a4)
  217.     bsr    ReplyPacket
  218.  
  219. inireq:    lea    intuiname(pc),a1    ;init "unknown packet" requester
  220.     moveq    #36,d0
  221.     CALL    OpenLibrary
  222.     move.l    d0,IntuiBase(a5)
  223.     beq.s    .A
  224.     lea    ReqStruct(a5),a0
  225.     moveq    #es_SIZEOF,d0
  226.     move.l    d0,(a0)+
  227.     clr.l    (a0)+
  228.     lea    reqtitle(pc),a1
  229.     move.l    a1,(a0)+
  230.     clr.l    (a0)+
  231.     lea    reqbutton(pc),a1
  232.     move.l    a1,(a0)+
  233. .A
  234.  
  235. args:    move.l    MyDeviceNode(a5),a1
  236.     move.l    dn_Startup(a1),a0
  237.     clr.l    dn_Startup(a1)
  238.     move.l    a0,d0
  239.     beq    .A
  240.     lea    TempPath(a5),a1
  241.     move.l    a1,a2
  242.     moveq    #MAXPATH-1,d0
  243.     bsr    CopyBSTR2Char
  244.     moveq    #DOS_RDARGS,d1
  245.     moveq    #0,d2
  246.     move.l    DosBase(a5),a6
  247.     CALL    AllocDosObject
  248.     move.l    d0,d3
  249.     beq    .A
  250.     move.l    a2,a0
  251. .D    move.b    (a0)+,d0
  252.     beq.s    .C
  253.     cmp.b    #"_",d0
  254.     bne.s    .D
  255.     move.b    #" ",-1(a0)
  256.     bra.s    .D
  257. .C    move.b    #LF,-1(a0)
  258.     clr.b    (a0)
  259.     sub.l    a2,a0
  260.     lea    TempName(a5),a3
  261.     move.l    a3,d2            ;Argument-Array
  262.     clr.l    (a3)+            ;clear it
  263.     clr.l    (a3)+
  264.     clr.l    (a3)+
  265.     clr.l    (a3)
  266.     move.l    d2,a3
  267.     move.l    d3,a1            ;Rd-Args-Struct
  268.     move.l    a2,(a1)+        ;CSource.Buffer
  269.     move.l    a0,(a1)            ;CSource.Length
  270.     lea    template(pc),a0
  271.     move.l    a0,d1            ;Template
  272.     CALL    ReadArgs        ;process Startup line
  273.     DBUG4    txargs,(a3),4(a3),8(a3),12(a3)
  274.     move.l    d0,d2
  275.     bne.s    .E
  276.     bsr    RequestReadArgs
  277.     bra.s    .A
  278. .E    move.l    (a3)+,d0
  279.     beq.s    .G
  280.     move.l    d0,a0
  281.     lea    VolumeName(a5),a1
  282.     moveq    #MAXNAME-2,d0
  283.     bsr    CopyChar2BSTR
  284.     move.l    d0,StupVolname(a5)
  285. .G    lea    StupIcon(a5),a0
  286.     move.l    (a3)+,d0
  287.     move.b    d0,(a0)+
  288.     move.l    (a3)+,d0
  289.     move.b    d0,(a0)+
  290.     move.l    (a3)+,d0
  291.     move.b    d0,(a0)+
  292.     move.l    d2,d1
  293.     CALL    FreeArgs
  294.     moveq    #DOS_RDARGS,d1
  295.     move.l    d3,d2
  296.     CALL    FreeDosObject
  297. .A    move.l    4.w,a6
  298.  
  299. volnod:    lea    VolumeNode(a5),a2    ;set up volume node
  300.     move.l    a2,d0
  301.     lsr.l    #2,d0
  302.     move.l    d0,MyVolumeBPTR(a5)
  303.     moveq    #2,d0
  304.     move.l    d0,dl_Type(a2)
  305.     move.l    MyMsgPort(a5),dl_Task(a2)
  306.     move.l    #"DOS"<<8,dl_DiskType(a2)
  307.     lea    volname1(pc),a0
  308.     tst.b    StupIcon(a5)
  309.     beq.s    .A
  310.     move.l    DosBase(a5),a0
  311.     move.l    dl_Root(a0),a0
  312.     move.l    rn_Info(a0),a0
  313.     add.l    a0,a0
  314.     add.l    a0,a0
  315.     move.l    di_DevInfo(a0),d0
  316.     move.l    d0,VolumeNode(a5)
  317.     move.l    MyVolumeBPTR(a5),di_DevInfo(a0)
  318.     lea    volname2(pc),a0
  319. .A    move.l    StupVolname(a5),d0
  320.     bne.s    .C
  321.     lea    VolumeName(a5),a1
  322.     moveq    #MAXNAME-2,d0
  323.     bsr    CopyChar2BSTR
  324. .C    move.l    d0,dl_Name(a2)
  325.  
  326. upconv:    bsr    InitConversion        ;init upper case table
  327.     lea    NotifyPort(a5),a2    ;create msgport for notify
  328.     move.b    #NT_MSGPORT,LN_TYPE(a2)
  329.     moveq    #-1,d0
  330.     CALL    AllocSignal
  331.     tst.l    d0
  332.     bmi    exit3
  333.     move.b    d0,NSignal(a5)
  334.     move.b    d0,MP_SIGBIT(a2)
  335.     move.l    MyProcess(a5),MP_SIGTASK(a2)
  336.     lea    MP_MSGLIST(a2),a0
  337.     move.b    #NT_MESSAGE,LH_TYPE(a0)
  338.     NEWLIST    a0
  339.     lea    PacketPort(a5),a2    ;create msgport for DOSpackets
  340.     move.b    #NT_MSGPORT,LN_TYPE(a2)
  341.     moveq    #-1,d0
  342.     CALL    AllocSignal
  343.     tst.l    d0
  344.     bmi    exit3
  345.     move.b    d0,PSignal(a5)
  346.     move.b    d0,MP_SIGBIT(a2)
  347.     move.l    MyProcess(a5),MP_SIGTASK(a2)
  348.     lea    MP_MSGLIST(a2),a0
  349.     move.b    #NT_MESSAGE,LH_TYPE(a0)
  350.     NEWLIST    a0
  351.     lea    RootDir(a5),a2        ;create Lock for DiskInfo
  352.     moveq    #ACCESS_READ,d2
  353.     bsr    CreateLock
  354.     move.l    d0,RootLock(a5)
  355.     beq    exit4
  356.  
  357. auto:    tst.b    StupNocopy(a5)        ;init autocopy
  358.     bne.s    .A
  359.     CALL    Forbid
  360.     move.l    DosBase(a5),a0
  361.     move.l    dl_Root(a0),a0
  362.     move.l    rn_Info(a0),a0
  363.     add.l    a0,a0
  364.     add.l    a0,a0
  365.     lea    di_DevInfo(a0),a2
  366. .C    move.l    (a2),d0
  367.     beq.s    .D
  368.     lsl.l    #2,d0
  369.     move.l    d0,a2
  370.     move.l    dol_Name(a2),a0
  371.     add.l    a0,a0
  372.     add.l    a0,a0
  373.     lea    sysdisk(pc),a1
  374.     moveq    #0,d0
  375.     move.b    (a0)+,d0
  376.     bra.s    .F
  377. .G    move.b    (a1)+,d1
  378.     cmp.b    (a0)+,d1
  379.     bne.s    .C
  380. .F    dbra    d0,.G
  381.     tst.b    (a1)
  382.     bne.s    .C
  383.     CALL    Permit
  384.     move.l    a2,Copyfrom(a5)
  385.     DBUG1    txcopy,Copyfrom(a5)
  386.     bra.s    .A
  387. .D    CALL    Permit
  388. .A
  389.  
  390. loop:    move.l    MyMsgPort(a5),a2    ;enter main loop
  391.     bsr    GetPacket
  392.     move.l    d0,a4
  393.     bsr    GetNotify
  394.     clr.l    dp_Res1(a4)
  395.     clr.l    dp_Res2(a4)
  396.     move.l    dp_Type(a4),d0
  397.     IFD    DEBUG
  398.     move.l    dp_Port(a4),a1
  399.     move.l    MP_SIGTASK(a1),a1
  400.     move.l    LN_NAME(a1),a1
  401.     DBUG5    txpack,d0,dp_Arg1(a4),dp_Arg2(a4),dp_Arg3(a4),a1
  402.     ENDC
  403.     move.l    d0,d1
  404.     swap    d1
  405.     tst.w    d1
  406.     bne.s    .A
  407.     lea    start(pc),a1
  408.     lea    JumpTable(pc),a2
  409.     moveq    #0,d2
  410. .C    move.w    (a2)+,d1
  411.     bpl.s    .E
  412. .A    DBUG1    txerr1,d0
  413.     bsr    RequestUnknown
  414.     move.w    #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
  415.     bra.s    .D
  416. .E    move.w    (a2)+,d2
  417.     cmp.w    d0,d1
  418.     bne.s    .C
  419.     add.l    d2,a1
  420.                 ;***
  421.     jsr    (a1)        ;jump into subroutine to process packet
  422.                 ;***
  423. .D    IFD    DEBUG
  424.     moveq    #DOS_TRUE,d0
  425.     cmp.l    dp_Res1(a4),d0
  426.     beq.s    .H
  427.     DBUG2    txres,dp_Res1(a4),dp_Res2(a4)
  428. .H    ENDC
  429.     bsr    ReplyPacket
  430.     bra    loop
  431.  
  432. AExit:    addq.l    #4,sp            ;exit routine
  433.     moveq    #DOS_TRUE,d0
  434.     move.l    d0,dp_Res1(a4)
  435.     bsr    ReplyPacket
  436.     IFND    DEBUG
  437.     move.l    NumLocks(a5),d0
  438.     subq.l    #1,d0
  439.     bne    loop
  440.     ENDC
  441.     move.l    RootLock(a5),a1
  442.     bsr    FreeLock
  443. exit4:    move.l    MyDeviceNode(a5),a0
  444.     clr.l    dn_Task(a0)
  445.     bsr    FlushPackets
  446.     tst.b    StupIcon(a5)
  447.     beq.s    .A
  448.     move.l    DosBase(a5),a0
  449.     move.l    dl_Root(a0),a0
  450.     move.l    rn_Info(a0),a0
  451.     add.l    a0,a0
  452.     add.l    a0,a0
  453.     move.l    VolumeNode(a5),d0
  454.     move.l    d0,di_DevInfo(a0)
  455.  
  456. .A    moveq    #0,d0
  457.     move.b    PSignal(a5),d0
  458.     CALL    FreeSignal
  459.     moveq    #0,d0
  460.     move.b    NSignal(a5),d0
  461.     CALL    FreeSignal
  462. exit3:    move.l    DosBase(a5),a1
  463.     CALL    CloseLibrary
  464. exit2:    move.l    MyDeviceNode(a5),a0
  465.     clr.l    dn_Task(a0)
  466.     DBUG3    txend,FileSize(a5),TotalSize(a5),NumLocks(a5)
  467.     move.l    MyMemPool(a5),d0
  468.     beq.s    .A
  469.     move.l    d0,a0
  470.     CALL    DeletePool
  471. .A    move.l    a5,a1
  472.     move.l    #My_SIZEOF,d0
  473.     CALL    FreeMem
  474. exit1:    movem.l    (sp)+,d2-d7/a2-a6
  475.     moveq    #0,d0
  476.     rts
  477.  
  478. *******************************************************
  479.  
  480. * table for branching from main to subroutine depending on the
  481. * current packet
  482.  
  483. JumpTable:
  484.     dc.w    ACTION_NIL,NoAction-start
  485.     dc.w    ACTION_SET_PROTECT,Unsupported-start
  486.     dc.w    ACTION_SET_COMMENT,Unsupported-start
  487.     dc.w    ACTION_SET_DATE,Unsupported-start
  488.     dc.w    ACTION_INHIBIT,Unsupported-start
  489.     dc.w    ACTION_FLUSH,NoAction-start
  490.     dc.w    ACTION_IS_FILESYSTEM,NoAction-start
  491.  
  492.     dc.w    ACTION_DIE,AExit-start
  493.     dc.w    ACTION_CURRENT_VOLUME,ACurrentVolume-start
  494.     dc.w    ACTION_RENAME_DISK,ARenameDisk-start
  495.     dc.w    ACTION_WRITE_PROTECT,AWriteProtect-start
  496.  
  497.     dc.w    ACTION_FINDUPDATE,AOpenReadWrite-start
  498.     dc.w    ACTION_FINDINPUT,AOpenOldfile-start
  499.     dc.w    ACTION_FINDOUTPUT,AOpenNewfile-start
  500.     dc.w    ACTION_END,ACloseFile-start
  501.     dc.w    ACTION_SEEK,ASeekPosition-start
  502.     dc.w    ACTION_READ,AReadFile-start
  503.     dc.w    ACTION_WRITE,AWriteFile-start
  504.     dc.w    ACTION_DELETE_OBJECT,ADeleteObject-start
  505.     dc.w    ACTION_RENAME_OBJECT,ARenameObject-start
  506.     dc.w    ACTION_CREATE_DIR,ACreateDir-start
  507.  
  508.     dc.w    ACTION_LOCATE_OBJECT,ALocateObject-start
  509.     dc.w    ACTION_PARENT,AParentDir-start
  510.     dc.w    ACTION_COPY_DIR,ADuplicateLock-start
  511.     dc.w    ACTION_FREE_LOCK,AFreeLock-start
  512.     dc.w    ACTION_SAME_LOCK,ASameLock-start
  513.     dc.w    ACTION_EXAMINE_OBJECT,AExamineObject-start
  514.     dc.w    ACTION_EXAMINE_ALL,Unsupported-start
  515.     dc.w    ACTION_EXAMINE_FH,AExamineFH-start
  516.     dc.w    ACTION_EXAMINE_ALL_END,Unsupported-start
  517.     dc.w    ACTION_EXAMINE_NEXT,AExamineNext-start
  518.     dc.w    ACTION_DISK_INFO,ADiskInfo1-start
  519.     dc.w    ACTION_INFO,ADiskInfo2-start
  520.  
  521.     dc.w    ACTION_ADD_NOTIFY,AAddNotify-start
  522.     dc.w    ACTION_REMOVE_NOTIFY,ARemoveNotify-start
  523.     dc.w    ACTION_SET_FILE_SIZE,ASetFileSize-start
  524.     dc.w    ACTION_FH_FROM_LOCK,AFHfromLock-start
  525.     dc.w    ACTION_CHANGE_MODE,AChangeMode-start
  526.     dc.w    ACTION_COPY_DIR_FH,ADupLockFromFH-start
  527.     dc.w    ACTION_PARENT_FH,AParentFromFH-start
  528.     dc.w    -1
  529.  
  530.  
  531. * strings
  532.  
  533. volname1    dc.b    "Env",0
  534. volname2    dc.b    "Environment",0
  535. intuiname    dc.b    "intuition.library",0
  536. reqtitle    dc.b    "HappyENV warning:",0
  537. requnknown    dc.b    "Task %s",LF,"uses packet %ld",0
  538. reqreadargs    dc.b    "Bad startup arguments",0
  539. reqbutton    dc.b    "Ok",0
  540. version        dc.b    "$VER: HappyENV-Handler 1.0 (05.06.97)",LF,0
  541. dosname        dc.b    "dos.library",0
  542. utilname    dc.b    "utility.library",0
  543. sysdisk        dc.b    "ENVARC",0
  544. template    dc.b    "VOLNAME/K,ICON/S,NOCOPY/S,NOREQ/S",0
  545.         IFD    EXPAND
  546. prefstx        dc.b    "prefs",0
  547. configtx    dc.b    "config",0
  548.         ENDC
  549.         even
  550.  
  551. *******************************************************
  552.  
  553. * Init to-upper-conversion table which allows
  554. * quick case independent compares
  555. InitConversion:
  556.     lea    CharTable(a5),a2
  557.     move.w    #255,d0
  558. .A    move.b    d0,0(a2,d0.w)
  559.     dbra    d0,.A
  560.     moveq    #"A",d0
  561. .C    move.b    d0,"a"-"A"(a2,d0.w)
  562.     addq.w    #1,d0
  563.     cmp.b    #"Z"+1,d0
  564.     bne.s    .C
  565.     move.w    #192,d0
  566. .F    move.b    d0,224-192(a2,d0.w)
  567.     addq.w    #1,d0
  568.     cmp.b    #222+1,d0
  569.     bne.s    .F
  570.  
  571.     lea    utilname(pc),a1        ;open utility.library
  572.     moveq    #37,d0
  573.     CALL    OpenLibrary
  574.     tst.l    d0
  575.     beq.s    .D
  576.     move.l    d0,a6
  577.     move.w    #255,d2
  578. .E    move.w    d2,d0
  579.     CALL    ToUpper
  580.     move.b    d0,0(a2,d2.w)
  581.     dbra    d2,.E
  582.     move.l    a6,a1
  583.     move.l    4.w,a6
  584.     CALL    CloseLibrary
  585. .D    rts
  586.  
  587. * Display requester for unknown packets
  588. RequestUnknown:
  589.     tst.b    StupNoreq(a5)
  590.     bne.s    .A
  591.     move.l    IntuiBase(a5),a6
  592.     move.l    a6,d0
  593.     beq.s    .A
  594.     lea    ReqStruct(a5),a1
  595.     lea    requnknown(pc),a0
  596.     move.l    a0,12(a1)
  597.     sub.l    a2,a2
  598.     lea    FormatArgs(a5),a3
  599.     move.l    dp_Type(a4),4(a3)
  600.     move.l    dp_Port(a4),a0
  601.     move.l    MP_SIGTASK(a0),a0
  602.     move.l    LN_NAME(a0),(a3)
  603.     sub.l    a0,a0
  604.     CALL    EasyRequestArgs
  605.     move.l    4.w,a6
  606. .A    rts
  607.  
  608. * Display requester for bad startup arguments
  609. RequestReadArgs:
  610.     move.l    IntuiBase(a5),a6
  611.     move.l    a6,d0
  612.     beq.s    .A
  613.     lea    ReqStruct(a5),a1
  614.     lea    reqreadargs(pc),a0
  615.     move.l    a0,12(a1)
  616.     sub.l    a2,a2
  617.     sub.l    a3,a3
  618.     sub.l    a0,a0
  619.     CALL    EasyRequestArgs
  620.     move.l    4.w,a6
  621. .A    rts
  622.  
  623. * Wait for a packet, then get it
  624. * ENTRY: a2=msgport
  625. * EXIT:  d0=packet
  626. GetPacket:
  627. .A    move.l    a2,a0
  628.     CALL    WaitPort
  629.     move.l    a2,a0
  630.     CALL    GetMsg
  631.     tst.l    d0
  632.     beq.s    .A
  633.     move.l    d0,a0
  634.     move.l    mn_Node+LN_NAME(a0),d0
  635.     beq.s    .A
  636.     rts
  637.  
  638. * Reply packet in a4
  639. ReplyPacket:
  640.     move.l    a4,a2
  641.     move.l    dp_Port(a4),a0        ;reply port
  642.     move.l    MyMsgPort(a5),dp_Port(a2)
  643. * More general reply packet
  644. * ENTRY: a2=packet to send, a0=msgport to send to
  645. SendPacket:
  646.     move.l    dp_Link(a2),a1        ;message to send
  647.     move.l    a2,mn_Node+LN_NAME(a1)
  648.     clr.l    mn_Node+LN_SUCC(a1)
  649.     clr.l    mn_Node+LN_PRED(a1)
  650.     move.b    #NT_MESSAGE,mn_Node+LN_TYPE(a1)
  651.     CALL    PutMsg
  652.     rts
  653.  
  654. * Reply all packets that are waiting to be processed (for exit)
  655. FlushPackets:
  656. .A    move.l    MyMsgPort(a5),a0
  657.     CALL    GetMsg
  658.     tst.l    d0
  659.     beq.s    .C
  660.     move.l    d0,a0
  661.     move.l    mn_Node+LN_NAME(a0),d0
  662.     beq.s    .A
  663.     move.l    d0,a4
  664.     clr.l    dp_Res1(a4)
  665.     move.w    #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
  666.     bsr    ReplyPacket
  667.     bra.s    .A
  668. .C    rts
  669.  
  670. * Send a packet to the handler in CopyfromPort and wait for a reply
  671. * ENTRY: d0=dp_Type, d1=dp_Arg1, d2=dp_Arg2, d3=dp_Arg3
  672. * EXIT:  d0=dp_Res1, d1=dp_Res2, Z-flag
  673. DoPacket:
  674.     move.l    a2,-(sp)
  675.     lea    MyPacket(a5),a1
  676.     lea    sp_Pkt(a1),a2
  677.     move.l    a1,dp_Link(a2)
  678.     lea    PacketPort(a5),a1
  679.     move.l    a1,dp_Port(a2)
  680.     move.l    d0,dp_Type(a2)
  681.     move.l    d1,dp_Arg1(a2)
  682.     move.l    d2,dp_Arg2(a2)
  683.     move.l    d3,dp_Arg3(a2)
  684.     move.l    CopyfromPort(a5),a0
  685.     bsr    SendPacket
  686.     lea    PacketPort(a5),a2
  687.     bsr    GetPacket
  688.     move.l    d0,a0
  689.     DBUG4    txpkt,a0,dp_Type(a0),dp_Res1(a0),dp_Res2(a0)
  690. ;    bsr    wait_c
  691.     move.l    dp_Res2(a0),d1
  692.     move.l    dp_Res1(a0),d0
  693.     move.l    (sp)+,a2
  694.     rts
  695.  
  696. *******************************************************
  697.  
  698. *******************************************************
  699.  
  700.  
  701. * Following there are all subroutines to process the individual packets
  702. * It starts with some general purpose and Filehandle handling ones.
  703.  
  704. * No action will be performed
  705. NoAction:
  706.     moveq    #DOS_TRUE,d0
  707.     move.l    d0,dp_Res1(a4)
  708.     rts
  709.  
  710. * For unsupported packets without showing a requester
  711. Unsupported:
  712.     DBUG1    txerr1,dp_Type(a4)
  713.     move.w    #ERROR_ACTION_NOT_KNOWN,dp_Res2+2(a4)
  714.     rts
  715.  
  716. ACurrentVolume:
  717.     move.l    MyVolumeBPTR(a5),dp_Res1(a4)
  718.     rts
  719.  
  720. ARenameDisk:
  721.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  722.     tst.b    WriteProtected(a5)
  723.     bne.s    .fail
  724.     move.l    dp_Arg1(a4),a0
  725.     lea    TempName(a5),a1
  726.     moveq    #MAXNAME-2,d0
  727.     bsr    CopyBSTR2Char
  728.     lea    TempName(a5),a0
  729.     lea    VolumeName(a5),a1
  730.     moveq    #MAXNAME-2,d0
  731.     bsr    CopyChar2BSTR
  732.     moveq    #DOS_TRUE,d0
  733.     move.l    d0,dp_Res1(a4)
  734. .fail    rts
  735.  
  736. AWriteProtect:
  737.     move.l    dp_Arg1(a4),d0
  738.     move.b    d0,WriteProtected(a5)
  739.     moveq    #DOS_TRUE,d0
  740.     move.l    d0,dp_Res1(a4)
  741.     rts    
  742.  
  743. AOpenReadWrite:
  744.     move.l    dp_Arg3(a4),a0
  745.     move.l    dp_Arg2(a4),d0
  746.     moveq    #ACCESS_READ,d2
  747.     bsr    LocateObject
  748.     bne.s    OpnOld
  749.     bra.s    AOpenNewfile
  750.  
  751. AOpenOldfile:
  752.     move.l    dp_Arg3(a4),a0
  753.     move.l    dp_Arg2(a4),d0
  754.     moveq    #ACCESS_READ,d2
  755.     bsr    LocateObject
  756. OpnOld:    move.l    dp_Arg1(a4),a3    ;label used by AOpenReadWrite and AFHFromLock
  757.     add.l    a3,a3
  758.     add.l    a3,a3
  759.     clr.l    fh_Interactive(a3)
  760.     move.l    d0,fh_Arg1(a3)
  761.     beq.s    .fail
  762.     move.l    d0,a0
  763.     move.l    myl_Key(a0),a1
  764.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  765.     tst.b    myf_Type(a1)        ;do not open dirs
  766.     bmi.s    .A
  767.     move.l    a0,a1
  768.     bsr    FreeLock
  769.     bra.s    .fail
  770. .A    move.l    myf_Size(a1),myl_Size(a0)
  771.     moveq    #0,d0
  772.     move.b    myf_DataOffs(a1),d0
  773.     add.l    d0,a1
  774.     move.l    a1,myl_Data(a0)
  775.     move.b    #1,myl_Mode(a0)
  776.     moveq    #DOS_TRUE,d0
  777.     move.l    d0,dp_Res1(a4)
  778.     DBUG1    txopeno,fh_Arg1(a3)
  779. .fail    rts
  780.  
  781. AOpenNewfile:
  782.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  783.     tst.b    WriteProtected(a5)
  784.     bne    .fail
  785.     move.w    #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
  786.     move.l    dp_Arg1(a4),a3
  787.     add.l    a3,a3
  788.     add.l    a3,a3
  789.     clr.l    fh_Interactive(a3)
  790.     move.l    dp_Arg2(a4),d0        ;does file already exist ?
  791.     move.l    dp_Arg3(a4),a0
  792.     bsr    DelSearchObject
  793.     beq.s    .A
  794.     move.l    d0,a1
  795.     tst.b    myf_Type(a1)        ;do not overwrite dirs
  796.     bpl    .fail
  797.     bsr    DeleteObject
  798.     beq    .fail
  799. .A    bsr    SplitPath
  800.     move.w    #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
  801.     move.l    dp_Arg2(a4),d0
  802.     bsr    CreatePath
  803.     beq    .fail
  804.     move.l    a3,-(sp)
  805.     move.l    d0,a3
  806.     lea    TempName(a5),a2
  807.     moveq    #0,d2
  808.     bsr    CreateNewObject
  809.     move.l    (sp)+,a3
  810.     beq.s    .fail
  811.     move.l    d0,a2
  812.     moveq    #ACCESS_WRITE,d2
  813.     bsr    CreateLock
  814.     move.l    d0,fh_Arg1(a3)
  815.     beq.s    .fail
  816.     move.l    d0,a0
  817.     move.b    #-1,myl_Mode(a0)
  818.     moveq    #DOS_TRUE,d0
  819.     move.l    d0,dp_Res1(a4)
  820.     DBUG1    txopenn,fh_Arg1(a3)
  821. .fail    rts
  822.  
  823. ACloseFile:
  824.     move.l    dp_Arg1(a4),a1
  825.     tst.b    myl_Mode(a1)
  826.     bmi.s    .D
  827.     bsr    FreeLock
  828.     bra.s    .ok
  829. .D    move.l    myl_Size(a1),d2
  830.     move.l    myl_Key(a1),a2
  831.     move.l    myf_Parent(a2),a3
  832.     lea    myf_Name(a2),a2
  833.     bsr    CreateNewObject
  834.     beq.s    .fail
  835.     move.l    d0,d4
  836.     move.l    d0,a3
  837.     add.l    d1,a3
  838.     move.l    dp_Arg1(a4),a2
  839.     bsr    CopyBlocksToMem
  840.     move.l    a2,a1
  841.     move.l    myl_Key(a2),a2
  842.     bsr    FreeLock
  843.     move.l    a2,a1
  844.     bsr    DeleteObj
  845.     beq.s    .fail
  846.     move.l    d4,a0
  847.     bsr    CheckNotify
  848. .ok    moveq    #DOS_TRUE,d0
  849.     move.l    d0,dp_Res1(a4)
  850. .fail    rts
  851.  
  852. * Copy all blocks of a filehandle to memory
  853. * ENTRY: a2=lock, a3=destination memory
  854. * EXIT: nothing (some registers changed)
  855. * USED BY: ACloseFile, ASetFileSize
  856. CopyBlocksToMem:
  857.     move.l    myl_Start(a2),d3
  858. .F    tst.l    d3
  859.     beq.s    .A
  860.     move.l    d3,-(sp)
  861.     move.l    d3,a0
  862.     move.l    (a0)+,d3
  863.     move.l    (a0)+,d2
  864.     move.l    a3,a1
  865.     move.l    d2,d0
  866.     CALL    CopyMem
  867.     add.l    d2,a3
  868.     move.l    d2,d0
  869.     addq.l    #8,d0
  870.     move.l    (sp)+,a1
  871.     bsr    FreeMem
  872.     bra.s    .F
  873. .A    rts
  874.  
  875. AWriteFile:
  876.     moveq    #-1,d0
  877.     move.l    d0,dp_Res1(a4)
  878.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  879.     tst.b    WriteProtected(a5)
  880.     bne    .fail
  881.     move.l    dp_Arg1(a4),a2        ;lock
  882.     move.l    dp_Arg2(a4),a3        ;buffer
  883.     move.l    dp_Arg3(a4),d3        ;length
  884.  
  885.     bsr    ReadToWriteMode
  886.     beq    .fail
  887. .F    move.l    d3,d2
  888.     move.l    myl_Block(a2),d0
  889.     beq.s    .E
  890.     move.l    d0,a1
  891.     move.l    4(a1),d0
  892.     sub.l    myl_BlockPos(a2),d0
  893.     beq.s    .C
  894.     bmi.s    .C
  895.     MIN    d0,d2,G
  896. .D    addq.l    #8,a1
  897.     add.l    myl_BlockPos(a2),a1
  898.     move.l    a3,a0
  899.     move.l    d2,d0
  900.     CALL    CopyMem
  901.     DBUG2    txwins,d2,myl_Pos(a2)
  902.     add.l    d2,a3
  903.     add.l    d2,myl_Pos(a2)
  904.     add.l    d2,myl_BlockPos(a2)
  905.     sub.l    d2,d3
  906.     beq.s    .ok
  907.     bra.s    .F
  908. .C    move.l    (a1),d0
  909.     beq.s    .E
  910.     move.l    d0,myl_Block(a2)
  911.     clr.l    myl_BlockPos(a2)
  912.     bra.s    .F    
  913.     
  914. .E    bsr    AppendNewBlock
  915.     beq.s    .fail
  916.     clr.w    dp_Res2+2(a4)
  917.     move.l    a3,a0
  918.     move.l    d3,d0
  919.     CALL    CopyMem
  920.     add.l    d3,myl_Pos(a2)
  921.     move.l    d3,myl_BlockPos(a2)
  922. .ok    move.l    dp_Arg3(a4),dp_Res1(a4)
  923.     DBUG3    txwrite,dp_Arg3(a4),myl_Pos(a2),myl_Size(a2)
  924. .fail    rts
  925.  
  926. ASetFileSize:
  927.     moveq    #-1,d0
  928.     move.l    d0,dp_Res1(a4)
  929.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  930.     tst.b    WriteProtected(a5)
  931.     bne    .fail
  932.     move.w    #ERROR_SEEK_ERROR,dp_Res2+2(a4)
  933.     move.l    dp_Arg1(a4),a2        ;a2=lock
  934.     move.l    dp_Arg2(a4),d3        ;d3=position to truncate
  935.     move.l    dp_Arg3(a4),d2        ;d2=mode
  936.     move.l    myl_Size(a2),d4        ;d4=old size
  937.     moveq    #OFFSET_BEGINNING,d0
  938.     cmp.l    d0,d2
  939.     beq.s    .E
  940.     moveq    #OFFSET_END,d0
  941.     cmp.l    d0,d2
  942.     bne.s    .C
  943.     add.l    d4,d3
  944.     bra.s    .E
  945. .C    moveq    #OFFSET_CURRENT,d0
  946.     cmp.l    d0,d2
  947.     bne    .fail
  948.     add.l    myl_Pos(a2),d3
  949. .E    DBUG2    txsize,myl_Key(a2),d4,d3
  950.     tst.l    d3            ;d3=new size
  951.     bmi    .fail
  952.     cmp.l    d4,d3
  953.     beq.s    .ok            ;size will not change
  954.     bhi.s    .A            ;append some data
  955.  
  956.     move.l    d3,myl_Size(a2)        ;truncate some data
  957.     MIN    d3,myl_Pos(a2),F
  958.     bsr    ReadToWriteMode
  959.     beq.s    .fail
  960.     cmp.b    #1,d0
  961.     beq.s    .ok
  962.     move.l    myl_Pos(a2),myl_BlockPos(a2)
  963.     move.l    d3,d0
  964.     beq.s    .D
  965.     bsr    CreateNewBlock
  966.     beq.s    .fail
  967. .D    move.l    myl_Start(a2),d4
  968.     move.l    d0,myl_Block(a2)
  969.     move.l    d0,myl_Start(a2)
  970.     move.l    a1,a3
  971. .J    tst.l    d4
  972.     beq.s    .ok
  973.     move.l    d4,-(sp)
  974.     move.l    d4,a0
  975.     move.l    (a0)+,d4
  976.     move.l    (a0)+,d2
  977.     cmp.l    d2,d3
  978.     bls.s    .G
  979.     move.l    d2,d0
  980.     sub.l    d2,d3
  981.     bra.s    .H
  982. .G    move.l    d3,d0
  983.     beq.s    .I
  984.     moveq    #0,d3
  985. .H    move.l    a3,a1
  986.     CALL    CopyMem
  987. .I    add.l    d2,a3
  988.     move.l    d2,d0
  989.     addq.l    #8,d0
  990.     move.l    (sp)+,a1
  991.     bsr    FreeMem
  992.     bra.s    .J
  993.  
  994. .A    bsr    ReadToWriteMode        ;append some data
  995.     beq.s    .fail
  996.     sub.l    d4,d3
  997.     bsr    AppendNewBlock
  998.     beq.s    .fail
  999. .ok    move.l    myl_Size(a2),dp_Res1(a4)
  1000. .fail    rts
  1001.  
  1002.  
  1003. * Convert Lock from Read to Write mode
  1004. * ENTRY: a2=lock
  1005. * EXIT:  d0,Z=success (0=fail, 1=changed, 2=not changed)
  1006. * USED BY: AWriteFile, ASetFileSize
  1007. ReadToWriteMode:
  1008.     moveq    #2,d0
  1009.     tst.b    myl_Mode(a2)
  1010.     bmi.s    .ok
  1011.     move.w    #ERROR_WRITE_PROTECTED,dp_Res2+2(a4)
  1012.     move.l    myl_Key(a2),a0
  1013.     cmp.b    #1,myf_Locks(a0)
  1014.     bhi.s    .fail
  1015.     move.l    myl_Size(a2),d0
  1016.     beq.s    .A
  1017.     bsr    CreateNewBlock
  1018.     beq.s    .fail
  1019. .A    move.l    d0,myl_Block(a2)
  1020.     move.l    d0,myl_Start(a2)
  1021.     move.l    myl_Pos(a2),myl_BlockPos(a2)
  1022.     move.b    #-1,myl_Mode(a2)
  1023.     move.l    myl_Key(a2),a0
  1024.     move.b    #-1,myf_Locks(a0)
  1025.     move.l    myl_Data(a2),a0
  1026.     move.l    myl_Size(a2),d0
  1027.     beq.s    .C
  1028.     CALL    CopyMem
  1029. .C    DBUG2    txchng,myl_Key(a2),myl_Pos(a2),myl_Size(a2)
  1030.     moveq    #1,d0
  1031. .ok    rts
  1032. .fail    moveq    #0,d0
  1033.     rts
  1034.  
  1035. * Create and append a new block as last one to block list
  1036. * ENTRY: d3=size, a2=lock
  1037. * EXIT:  d0,Z=success, a1=newblock+8
  1038. * USED BY: AWriteFile, ASetFileSize
  1039. AppendNewBlock:
  1040.     move.l    d3,d0
  1041.     bsr    CreateNewBlock
  1042.     beq.s    .fail
  1043.     add.l    d3,myl_Size(a2)
  1044.     move.l    myl_Block(a2),a0
  1045.     move.l    d0,myl_Block(a2)
  1046.     move.l    a0,d1
  1047.     bne.s    .A
  1048.     lea    myl_Start(a2),a0
  1049. .A    move.l    (a0),d1            ;look for end of blocks
  1050.     beq.s    .C            ; for SetFileSize
  1051.     move.l    d1,a0
  1052.     bra.s    .A
  1053. .C    move.l    d0,(a0)            ;insert new block as last
  1054.     moveq    #1,d0
  1055. .fail    rts
  1056.  
  1057. * Allocates memory for a new block
  1058. * ENTRY: d0=size
  1059. * EXIT:  d0=block , a1=block+8
  1060. * USED BY: AppendNewBlock, ReadToWriteMode, ASetFileSIze
  1061. CreateNewBlock:
  1062.     move.w    #ERROR_DISK_FULL,dp_Res2+2(a4)
  1063.     move.l    d0,-(sp)
  1064.     addq.l    #8,d0
  1065.     bsr    AllocMem
  1066.     beq.s    .fail
  1067.     move.l    d0,a1
  1068.     clr.l    (a1)+
  1069.     move.l    (sp),(a1)+
  1070. .fail    addq.l    #4,sp
  1071.     tst.l    d0
  1072.     rts
  1073.  
  1074. AReadFile:
  1075.     move.l    dp_Arg1(a4),a2        ;lock
  1076.     move.l    dp_Arg2(a4),a3        ;buffer
  1077.     move.l    myl_Size(a2),d0
  1078.     move.l    myl_Pos(a2),a0
  1079.     sub.l    a0,d0
  1080.     move.l    dp_Arg3(a4),d3        ;length
  1081.     MIN    d0,d3,G
  1082.     clr.w    dp_Res2+2(a4)
  1083.     DBUG3    txread,d3,dp_Arg3(a4),myl_Pos(a2)
  1084.     add.l    d3,myl_Pos(a2)
  1085.     move.l    d3,dp_Res1(a4)
  1086.     beq.s    .ok
  1087.     tst.b    myl_Mode(a2)
  1088.     bpl.s    .E
  1089.  
  1090. .F    move.l    d3,d2
  1091.     move.l    myl_Block(a2),a0
  1092.     move.l    4(a0),d0
  1093.     sub.l    myl_BlockPos(a2),d0
  1094.     beq.s    .C
  1095.     bmi.s    .C
  1096.     MIN    d0,d2,D
  1097.     addq.l    #8,a0
  1098.     add.l    myl_BlockPos(a2),a0
  1099.     move.l    a3,a1
  1100.     move.l    d2,d0
  1101.     CALL    CopyMem
  1102.     add.l    d2,a3
  1103.     add.l    d2,myl_BlockPos(a2)
  1104.     sub.l    d2,d3
  1105.     beq.s    .ok
  1106.     bra.s    .F
  1107. .C    move.l    (a1),d0
  1108.     beq.s    .ok
  1109.     move.l    d0,myl_Block(a2)
  1110.     clr.l    myl_BlockPos(a2)
  1111.     bra    .F
  1112.  
  1113. .E    move.l    myl_Data(a2),d0
  1114.     add.l    d0,a0
  1115.     move.l    a3,a1
  1116.     move.l    d3,d0
  1117.     CALL    CopyMem
  1118. .ok    rts
  1119.  
  1120. ASeekPosition
  1121.     move.l    dp_Arg1(a4),a2        ;a2=lock
  1122.     move.l    dp_Arg2(a4),d1        ;d1=position
  1123.     move.l    dp_Arg3(a4),d2        ;d2=mode
  1124.     clr.w    dp_Res2+2(a4)
  1125.     move.l    myl_Pos(a2),d3        ;d3=old pos
  1126.     move.l    myl_Size(a2),d4        ;d4=size
  1127.  
  1128.     moveq    #OFFSET_BEGINNING,d0
  1129.     cmp.l    d0,d2
  1130.     beq.s    .E
  1131.     moveq    #OFFSET_END,d0
  1132.     cmp.l    d0,d2
  1133.     bne.s    .C
  1134.     add.l    d4,d1
  1135.     bra.s    .E
  1136. .C    moveq    #OFFSET_CURRENT,d0
  1137.     cmp.l    d0,d2
  1138.     bne.s    .fail
  1139.     add.l    d3,d1
  1140. .E    move.l    d1,myl_Pos(a2)
  1141.     bmi.s    .A
  1142.     cmp.l    d1,d4
  1143.     bhs.s    Seeek
  1144.     move.l    d4,myl_Pos(a2)
  1145.     bra.s    .fail
  1146. .A    clr.l    myl_Pos(a2)
  1147. .fail    move.w    #ERROR_SEEK_ERROR,dp_Res2+2(a4)
  1148.     moveq    #-1,d3
  1149.  
  1150. Seeek    tst.b    myl_Mode(a2)    ;label not used globally
  1151.     bpl.s    .A
  1152.     move.l    myl_Pos(a2),d2
  1153.     move.l    myl_Start(a2),d0
  1154.     beq.s    .A
  1155.     bra.s    .E
  1156. .D    move.l    (a0),d0
  1157.     beq.s    .C
  1158. .E    move.l    d0,a0
  1159.     move.l    4(a0),d1
  1160.     sub.l    d1,d2
  1161.     beq.s    .F
  1162.     bpl.s    .D
  1163. .F    add.l    d1,d2
  1164. .C    move.l    a0,myl_Block(a2)
  1165.     move.l    d2,myl_BlockPos(a2)
  1166. .A    move.l    d3,dp_Res1(a4)
  1167.     DBUG1    txseek,myl_Pos(a2)
  1168.     rts
  1169.  
  1170. ADeleteObject:
  1171.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  1172.     tst.b    WriteProtected(a5)
  1173.     bne.s    .fail
  1174.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1175.     move.l    dp_Arg1(a4),d0
  1176.     move.l    dp_Arg2(a4),a0
  1177.     bsr    SearchObject
  1178.     beq.s    .fail
  1179.     movem.l    d0-d1,-(sp)
  1180.     move.l    d0,a0
  1181.     moveq    #1,d0
  1182.     bsr    NotifyObject
  1183.     movem.l    (sp)+,d0-d1
  1184.     move.l    d0,a1
  1185.     bsr    DeleteObject
  1186.     beq.s    .fail
  1187.     moveq    #DOS_TRUE,d0
  1188.     move.l    d0,dp_Res1(a4)
  1189. .fail    rts
  1190.  
  1191. ARenameObject:
  1192.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  1193.     tst.b    WriteProtected(a5)
  1194.     bne    .fail
  1195.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1196.     move.l    dp_Arg1(a4),d0
  1197.     move.l    dp_Arg2(a4),a0
  1198.     bsr    SearchObject
  1199.     beq    .fail
  1200.     move.l    d0,a3
  1201.     move.l    d1,d3
  1202.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1203.     tst.b    myf_Locks(a3)
  1204.     bne    .fail
  1205.     move.l    a3,a0
  1206.     bsr    NotifyObject
  1207.     move.w    #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
  1208.     move.l    dp_Arg3(a4),d0
  1209.     move.l    dp_Arg4(a4),a0
  1210.     bsr    DelSearchObject
  1211.     bne    .fail
  1212.     bsr    SplitPath
  1213.     move.w    #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
  1214.     move.l    dp_Arg3(a4),d0
  1215.     bsr    SearchPath
  1216.     beq    .fail
  1217.     move.l    a3,-(sp)
  1218.     moveq    #0,d2
  1219.     tst.b    myf_Type(a3)
  1220.     bpl.s    .D
  1221.     move.l    myf_Size(a3),d2
  1222. .D    move.l    d0,a3
  1223.     lea    TempName(a5),a2
  1224.     bsr    CreateNewObject
  1225.     move.l    (sp)+,a3
  1226.     beq.s    .fail
  1227.     move.l    d0,a2
  1228.     move.b    myf_Type(a3),myf_Type(a2)
  1229.     bpl.s    .A
  1230.     move.l    a2,a1            ;rename file
  1231.     add.l    d1,a1
  1232.     move.l    a3,a0
  1233.     moveq    #0,d0
  1234.     move.b    myf_DataOffs(a3),d0
  1235.     add.l    d0,a0
  1236.     move.l    myf_Size(a3),d0
  1237.     CALL    CopyMem
  1238.     bra.s    .C
  1239. .A    move.l    myf_First(a3),d0    ;rename dir
  1240.     clr.l    myf_First(a3)
  1241.     move.l    d0,myf_First(a2)
  1242.     beq.s    .C
  1243. .E    move.l    d0,a0
  1244.     move.l    a2,myf_Parent(a0)
  1245.     move.l    myf_Link(a0),d0
  1246.     bne.s    .E
  1247. .C    move.l    d3,d1            ;end rename
  1248.     move.l    a3,a1
  1249.     bsr    DeleteObject
  1250.     beq.s    .fail
  1251.     move.l    a2,a0
  1252.     bsr    CheckNotify
  1253.     moveq    #DOS_TRUE,d0
  1254.     move.l    d0,dp_Res1(a4)
  1255. .fail    rts
  1256.  
  1257. *******************************************************
  1258.  
  1259. * Here are subroutines for packets that deal with Locks. 
  1260.  
  1261. ALocateObject:
  1262.     move.l    dp_Arg1(a4),d0
  1263.     move.l    dp_Arg2(a4),a0
  1264.     move.l    dp_Arg3(a4),d2
  1265.     bsr    LocateObject
  1266.     lsr.l    #2,d0
  1267.     move.l    d0,dp_Res1(a4)
  1268.     rts
  1269.  
  1270. ADupLockFromFH:
  1271.     move.l    dp_Arg1(a4),d0
  1272.     bra.s    DupLock
  1273.  
  1274. ADuplicateLock:
  1275.     move.l    dp_Arg1(a4),d0
  1276.     lsl.l    #2,d0
  1277. DupLock    beq.s    .fail        ;label not used globally
  1278.     move.l    d0,a0
  1279.     move.l    myl_Key(a0),a2
  1280.     moveq    #ACCESS_READ,d2
  1281.     bsr    CreateLock
  1282.     lsr.l    #2,d0
  1283.     move.l    d0,dp_Res1(a4)
  1284. .fail    rts
  1285.  
  1286. AParentFromFH:
  1287.     move.l    dp_Arg1(a4),d0
  1288.     bra.s    ParentD
  1289. AParentDir:
  1290.     move.l    dp_Arg1(a4),d0
  1291.     lsl.l    #2,d0
  1292. ParentD    beq.s    .fail        ;label not used globally
  1293.     move.l    d0,a0
  1294.     move.l    myl_Key(a0),a2
  1295.     move.l    myf_Parent(a2),d0
  1296.     beq.s    .fail
  1297.     move.l    d0,a2
  1298.     moveq    #ACCESS_READ,d2
  1299.     bsr    CreateLock
  1300.     lsr.l    #2,d0
  1301.     move.l    d0,dp_Res1(a4)
  1302. .fail    rts
  1303.  
  1304. AFreeLock:
  1305.     move.l    dp_Arg1(a4),d0
  1306.     beq.s    .fail
  1307.     lsl.l    #2,d0
  1308.     move.l    d0,a1
  1309.     bsr    FreeLock
  1310.     moveq    #DOS_TRUE,d0
  1311.     move.l    d0,dp_Res1(a4)
  1312. .fail    rts
  1313.  
  1314. ASameLock:
  1315.     tst.b    StupIcon(a5)
  1316.     bne    Unsupported
  1317.     moveq    #LOCK_SAME_VOLUME,d0
  1318.     move.l    d0,dp_Res1(a4)
  1319.     move.l    dp_Arg1(a4),a0
  1320.     add.l    a0,a0
  1321.     add.l    a0,a0
  1322.     move.l    dp_Arg2(a4),a1
  1323.     add.l    a1,a1
  1324.     add.l    a1,a1
  1325.     move.l    myl_Key(a0),d0
  1326.     cmp.l    myl_Key(a1),d0
  1327.     bne.s    .A
  1328.     moveq    #LOCK_SAME,d0
  1329.     move.l    d0,dp_Res1(a4)
  1330. .A    rts
  1331.  
  1332. AExamineFH:
  1333.     move.l    dp_Arg1(a4),a0
  1334.     bra.s    Exammi
  1335.  
  1336. AExamineObject:
  1337.     move.l    dp_Arg1(a4),a0
  1338.     add.l    a0,a0
  1339.     add.l    a0,a0
  1340. Exammi    move.l    myl_Key(a0),a0    ;label not used globally
  1341.     move.l    dp_Arg2(a4),a1
  1342.     add.l    a1,a1
  1343.     add.l    a1,a1
  1344.     DBUG1    txexam,a0
  1345.     move.l    a1,a2
  1346.     moveq    #fib_SIZEOF/4-1,d0
  1347. .D    clr.l    (a2)+
  1348.     dbra    d0,.D
  1349. * Fill FileInfoBlock (fib) with infos about the object
  1350. * Used by AExamineFH, AExamineObject and AExamineNext
  1351. * ENTRY: a0=file, a1=fib
  1352. ExamineObject:
  1353.     moveq    #1,d0
  1354.     tst.l    myf_Parent(a0)
  1355.     beq.s    .C            ;rootdir ?
  1356.     IFD    DEBUG
  1357.     btst    #6,myf_Type(a0)
  1358.     beq.s    .D            ;hidden file ?
  1359.     moveq    #-3,d0
  1360.     bra.s    .C
  1361. .D    ENDC
  1362.     moveq    #-3,d0
  1363.     tst.b    myf_Type(a0)
  1364.     bmi.s    .C            ;file ?
  1365.     moveq    #2,d0            ;dir
  1366. .C    moveq    #0,d1
  1367.     move.l    d0,fib_DirEntryType(a1)
  1368.     move.l    d0,fib_EntryType(a1)
  1369.     bpl.s    .A
  1370.     move.l    myf_Size(a0),d1        ;no file no size
  1371. .A    move.l    a0,fib_DiskKey(a1)
  1372.     move.l    d1,fib_Size(a1)        ;calc size
  1373.     add.l    #1023,d1
  1374.     lsr.l    #8,d1
  1375.     lsr.l    #2,d1
  1376.     move.l    d1,fib_NumBlocks(a1)
  1377.     moveq    #2,d0
  1378.     move.b    myf_Type(a0),d1
  1379.     btst    #5,d1            ;copied ? -> A
  1380.     beq.s    .F
  1381.     bset    #4,d0
  1382. .F    btst    #4,d1            ;notify ? -> P
  1383.     beq.s    .G
  1384.     bset    #5,d0
  1385. .G    IFD    DEBUG
  1386.     btst    #6,d1            ;hidden ? -> H
  1387.     beq.s    .J
  1388.     bset    #7,d0
  1389. .J    tst.b    myf_Locks(a0)
  1390.     beq.s    .H
  1391.     bmi.s    .I
  1392.     bset    #2,d0            ;read-locked ?  -> no W
  1393.     bra.s    .H
  1394. .I    bset    #3,d0            ;write-locked ? -> no R
  1395. .H    ENDC
  1396.     move.l    d0,fib_Protection(a1)
  1397.     move.l    StartDate+0(a5),fib_DateStamp+0(a1)
  1398.     move.l    StartDate+4(a5),fib_DateStamp+4(a1)
  1399.     move.l    StartDate+8(a5),fib_DateStamp+8(a1)
  1400.     lea    myf_Name(a0),a0
  1401.     DBUG1    txexan,a0
  1402.     lea    fib_FileName(a1),a1
  1403.     moveq    #106,d0
  1404.     bsr    CopyChar2BSTR
  1405.     moveq    #DOS_TRUE,d0
  1406.     move.l    d0,dp_Res1(a4)
  1407.     rts
  1408.  
  1409. AExamineNext:
  1410.     move.l    dp_Arg1(a4),a2
  1411.     add.l    a2,a2
  1412.     add.l    a2,a2
  1413.     move.l    dp_Arg2(a4),a1
  1414.     add.l    a1,a1
  1415.     add.l    a1,a1
  1416.     move.l    fib_DiskKey(a1),a0
  1417.     DBUG1    txexnx,a0
  1418.     cmp.l    myl_Key(a2),a0
  1419.     bne.s    .A
  1420.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  1421.     tst.b    myf_Type(a0)
  1422.     bmi.s    .fail
  1423.     move.l    myf_First-myf_Link(a0),a0
  1424.     bra.s    .C
  1425. .A    move.l    myf_Link(a0),a0
  1426. .C    move.w    #ERROR_NO_MORE_ENTRIES,dp_Res2+2(a4)
  1427.     move.l    a0,d0
  1428.     beq.s    .fail
  1429.     IFND    DEBUG
  1430.     btst    #6,myf_Type(a0)
  1431.     bne.s    .A
  1432.     ENDC
  1433.     bra    ExamineObject
  1434. .fail    rts
  1435.  
  1436. ADiskInfo1:
  1437.     move.l    dp_Arg1(a4),a0
  1438.     bra.s    DiskInfo
  1439. ADiskInfo2:
  1440.     move.l    dp_Arg2(a4),a0
  1441. * ENTRY: a0=buffer (BPTR)
  1442. DiskInfo:            ;label not used globally
  1443.     add.l    a0,a0
  1444.     add.l    a0,a0
  1445.     move.l    a0,a1
  1446.     moveq    #id_SIZEOF/4-1,d0
  1447. .D    clr.l    (a1)+
  1448.     dbra    d0,.D
  1449.     IFD    DEBUG
  1450.     move.l    NumLocks(a5),id_NumSoftErrors(a0)
  1451.     ENDC
  1452.     moveq    #ID_VALIDATED,d0
  1453.     tst.b    WriteProtected(a5)
  1454.     beq.s    .C
  1455.     moveq    #ID_WRITE_PROTECTED,d0
  1456. .C    move.l    d0,id_DiskState(a0)
  1457.     move.l    #1024,d1
  1458.     move.l    d1,id_BytesPerBlock(a0)
  1459.     lsr.l    #1,d1
  1460.     move.l    FileSize(a5),d0
  1461.     add.l    d1,d0
  1462.     lsr.l    #8,d0
  1463.     lsr.l    #2,d0
  1464.     move.l    d0,id_NumBlocksUsed(a0)
  1465.     move.l    TotalSize(a5),d0
  1466.     add.l    d1,d0
  1467.     lsr.l    #8,d0
  1468.     lsr.l    #2,d0
  1469.     bne.s    .A
  1470.     moveq    #1,d0
  1471. .A    move.l    d0,id_NumBlocks(a0)
  1472.     move.l    #"DOS"<<8,id_DiskType(a0)
  1473.     move.l    MyVolumeBPTR(a5),id_VolumeNode(a0)
  1474.     move.l    RootLock(a5),id_InUse(a0)
  1475.     moveq    #DOS_TRUE,d0
  1476.     move.l    d0,dp_Res1(a4)
  1477.     rts
  1478.  
  1479. ACreateDir:
  1480.     move.w    #ERROR_DISK_WRITE_PROTECTED,dp_Res2+2(a4)
  1481.     tst.b    WriteProtected(a5)
  1482.     bne.s    .fail
  1483.     move.w    #ERROR_OBJECT_EXISTS,dp_Res2+2(a4)
  1484.     move.l    dp_Arg1(a4),d0
  1485.     move.l    dp_Arg2(a4),a0
  1486.     bsr    DelSearchObject
  1487.     bne.s    .fail
  1488.     bsr    SplitPath
  1489.     move.w    #ERROR_DIR_NOT_FOUND,dp_Res2+2(a4)
  1490.     move.l    dp_Arg1(a4),d0
  1491.     bsr    CreatePath
  1492.     beq.s    .fail
  1493.     move.l    d0,a3
  1494.     lea    TempName(a5),a2
  1495.     moveq    #0,d2
  1496.     bsr    CreateNewObject
  1497.     beq.s    .fail
  1498.     move.l    d0,a2
  1499.     clr.b    myf_Type(a2)
  1500.     moveq    #ACCESS_WRITE,d2
  1501.     bsr    CreateLock
  1502.     beq.s    .fail
  1503.     move.l    d0,a0
  1504.     lsr.l    #2,d0
  1505.     move.l    d0,dp_Res1(a4)
  1506.     move.l    myl_Key(a0),a0
  1507.     bsr    CheckNotify
  1508. .fail    rts
  1509.  
  1510. *******************************************************
  1511.  
  1512. * Here are subroutines that deal with Locks and Filehandles
  1513.  
  1514. AFHfromLock:
  1515.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  1516.     move.l    dp_Arg2(a4),d0
  1517.     beq.s    .fail
  1518.     lsl.l    #2,d0
  1519.     move.l    d0,a0
  1520.     move.l    myl_Key(a0),a0
  1521.     tst.b    myf_Type(a0)        ;do not open dirs
  1522.     bmi    OpnOld
  1523. .fail    rts
  1524.  
  1525. AChangeMode:
  1526.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1527.     move.l    dp_Arg1(a4),d0
  1528.     move.l    dp_Arg2(a4),a2
  1529.     moveq    #CHANGE_FH,d1
  1530.     cmp.l    d0,d1
  1531.     bne.s    .A
  1532.     move.l    dp_Arg1(a4),a3
  1533.     add.l    a3,a3
  1534.     add.l    a3,a3
  1535.     move.l    fh_Arg1(a3),d0
  1536.     beq.s    .fail
  1537.     move.l    d0,a2
  1538.     bra.s    .C
  1539. .A    moveq    #CHANGE_LOCK,d1
  1540.     cmp.l    d0,d1
  1541.     bne.s    .fail
  1542. .C    move.l    myl_Key(a2),a0
  1543.     move.b    myf_Locks(a0),d0
  1544.     move.l    dp_Arg3(a4),d2
  1545.     moveq    #ACCESS_WRITE,d1
  1546.     cmp.l    d1,d2
  1547.     bne.s    .D
  1548.     cmp.b    d0,d1
  1549.     beq.s    .ok
  1550.     cmp.b    #1,d0
  1551.     bne.s    .fail
  1552.     move.b    d1,myf_Locks(a0)
  1553.     bra.s    .ok
  1554. .D    cmp.b    d0,d1
  1555.     bne.s    .E
  1556.     tst.l    myl_Start(a2)
  1557.     bne.s    .fail
  1558.     move.b    #1,myf_Locks(a0)
  1559. .E    moveq    #ACCESS_READ,d1
  1560. .ok    move.l    d1,myl_Access(a2)
  1561.     moveq    #DOS_TRUE,d0
  1562.     move.l    d0,dp_Res1(a4)
  1563. .fail    rts
  1564.  
  1565. *******************************************************
  1566.  
  1567. * Here are subroutines for notification support
  1568.  
  1569. AAddNotify:
  1570.     move.w    #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
  1571.     move.l    dp_Arg1(a4),a3
  1572.     moveq    #myn_Name,d0
  1573.     move.l    nr_FullName(a3),a0
  1574. .C    addq.l    #1,d0
  1575.     tst.b    (a0)+
  1576.     bne.s    .C
  1577.     bsr    AllocMem
  1578.     beq.s    .fail
  1579.     move.l    d0,a2
  1580.     lea    NotifyList(a5),a0
  1581.     move.l    (a0),myn_Link(a2)
  1582.     move.l    a2,(a0)
  1583.     move.l    a3,myn_Request(a2)
  1584.     move.l    nr_FullName(a3),a0
  1585.     lea    myn_Name(a2),a1
  1586. .D    move.b    (a0)+,(a1)+
  1587.     bne.s    .D
  1588.     bsr    UpNoti
  1589.     IFD    DEBUG
  1590.     lea    myn_Name(a2),a0
  1591.     DBUG4    txanoti,a2,a3,a0,d0
  1592.     ENDC
  1593.     move.l    nr_Flags(a3),d1
  1594.     btst    #NRB_NOTIFY_INITIAL,d1    ;initial notify ?
  1595.     beq.s    .A
  1596.     tst.l    d0
  1597.     beq.s    .A
  1598.     move.l    d0,a0
  1599.     btst    #6,myf_Type(a0)        ;file really exists ?
  1600.     bne.s    .A
  1601.     bsr    SendNotify
  1602. .A    moveq    #DOS_TRUE,d0
  1603.     move.l    d0,dp_Res1(a4)
  1604. .fail    rts
  1605.  
  1606. ARemoveNotify:
  1607.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1608.     move.l    dp_Arg1(a4),a2
  1609.     tst.l    nr_MsgCount(a2)
  1610.     bne.s    .fail
  1611.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1612.     lea    NotifyList(a5),a1
  1613. .A    move.l    (a1),d0
  1614.     beq.s    .fail
  1615.     move.l    a1,a0
  1616.     move.l    d0,a1
  1617.     cmp.l    myn_Request(a1),a2
  1618.     bne.s    .A
  1619.     move.l    myn_Link(a1),myn_Link(a0)
  1620.     DBUG2    txrnoti,a1,a2
  1621.     move.l    myn_Key(a1),d0
  1622.     beq.s    .D
  1623.     move.l    d0,a0
  1624.     bclr    #4,myf_Type(a0)
  1625. .D    moveq    #myn_Name,d0
  1626.     lea    myn_Name(a1),a0
  1627. .C    addq.l    #1,d0
  1628.     tst.b    (a0)+
  1629.     bne.s    .C
  1630.     bsr    FreeMem
  1631.     moveq    #DOS_TRUE,d0
  1632.     move.l    d0,dp_Res1(a4)
  1633. .fail    rts
  1634.  
  1635. * Update myn_Key of notification list, mainly used by CheckNotify
  1636. * ENTRY: a0=file
  1637. UpdateNotify:
  1638.     move.l    a2,-(sp)
  1639.     lea    NotifyList(a5),a2
  1640.     bra.s    .A
  1641. .C    move.l    d0,a2
  1642.     tst.l    myn_Key(a2)
  1643.     bne.s    .A
  1644.     bsr.s    UpNoti
  1645.     IFD    DEBUG
  1646.     beq.s    .A
  1647.     lea    myn_Name(a2),a0
  1648.     DBUG2    txunoti,a0,d0
  1649.     ENDC
  1650. .A    move.l    (a2),d0
  1651.     bne.s    .C
  1652.     move.l    (sp)+,a2
  1653.     rts
  1654.  
  1655. * Subroutine used by UpdateNotify and AddNotify
  1656. UpNoti    lea    myn_Name(a2),a0
  1657.     lea    TempPath(a5),a1
  1658.     moveq    #MAXPATH-1,d0
  1659.     bsr    CopyChar2Char
  1660.     moveq    #0,d0
  1661.     bsr    SearchPath
  1662.     bne.s    .A
  1663.     moveq    #0,d0
  1664.     bsr    CalcFullName
  1665. .A    move.l    d0,myn_Key(a2)
  1666.     beq.s    .D
  1667.     move.l    d0,a0
  1668.     bset    #4,myf_Type(a0)
  1669. .D    rts
  1670.  
  1671. * Update notification list, check it for file/dir and parent dir
  1672. * and notify them.
  1673. * ENTRY: a0=file
  1674. CheckNotify:
  1675.     move.l    a0,-(sp)
  1676.     IFD    DEBUG
  1677.     lea    myf_Name(a0),a0
  1678.     DBUG1    txcnoti,a0
  1679.     ENDC
  1680.     bsr    UpdateNotify
  1681.     move.l    (sp)+,a0
  1682.  
  1683. * Check notification list for file/dir and parent dir and notify them.
  1684. * ENTRY: a0=file
  1685. NotifyObject:
  1686.     bsr    NotifyObj
  1687.     move.l    myf_Parent(a0),d1
  1688.     move.l    d1,a0
  1689.     beq.s    .E
  1690.     bsr    NotifyObj
  1691. .E    rts
  1692.  
  1693. * Notify object in a0, only used by NotifyObject
  1694. NotifyObj:
  1695.     movem.l    a2/a3,-(sp)
  1696.     lea    NotifyList(a5),a2
  1697.     bra.s    .A
  1698. .C    move.l    d0,a2
  1699.     cmp.l    myn_Key(a2),a0
  1700.     bne.s    .A
  1701.     move.l    a0,-(sp)
  1702.     move.l    myn_Request(a2),a3
  1703.     bsr    SendNotify
  1704.     move.l    (sp)+,a0
  1705. .A    move.l    (a2),d0
  1706.     bne.s    .C
  1707.     movem.l    (sp)+,a2/a3
  1708.     rts
  1709.  
  1710. * Send a Notify message or set a Notify signal
  1711. * ENTRY: a3=NotifyRequest
  1712. SendNotify:
  1713.     btst    #NRB_SEND_SIGNAL,nr_Flags+3(a3)
  1714.     beq.s    .C
  1715.     move.l    nr_Task(a3),a1
  1716.     IFD    DEBUG
  1717.     move.l    LN_NAME(a1),d0
  1718.     lea    myn_Name(a2),a0
  1719.     DBUG2    txsnoti,d0,a0
  1720.     ENDC
  1721.     moveq    #0,d0
  1722.     move.b    nr_SignalNum(a3),d1
  1723.     bset    d1,d0
  1724.     CALL    Signal
  1725.     rts
  1726.  
  1727. .C    btst    #NRB_SEND_MESSAGE,nr_Flags+3(a3)
  1728.     beq    .D
  1729.     moveq    #NotifyMessage_SIZEOF,d0
  1730.     bsr    AllocMem
  1731.     beq    .D
  1732.     move.l    d0,a0
  1733.     move.l    d0,a1
  1734.     moveq    #NotifyMessage_SIZEOF/2-1,d0
  1735. .A    clr.w    (a0)+
  1736.     dbra    d0,.A
  1737.     move.b    #NT_MESSAGE,LN_TYPE(a1)
  1738.     lea    NotifyPort(a5),a0
  1739.     move.l    a0,MN_REPLYPORT(a1)
  1740.     move.w    #NotifyMessage_SIZEOF,MN_LENGTH(a1)
  1741.     move.l    #$40000000,nm_Class(a1)
  1742.     move.w    #$1234,nm_Code(a1)
  1743.     move.l    a3,nm_NReq(a1)
  1744.     IFD    DEBUG
  1745.     move.l    a2,-(sp)
  1746.     move.l    nr_Port(a3),a0
  1747.     move.l    MP_SIGTASK(a0),a0
  1748.     move.l    LN_NAME(a0),a0
  1749.     lea    myn_Name(a2),a2
  1750.     DBUG3    txmnoti,a1,a0,a2
  1751.     move.l    (sp)+,a2
  1752.     ENDC
  1753.     move.l    nr_Port(a3),a0
  1754.     CALL    PutMsg
  1755.     addq.l    #1,nr_MsgCount(a3)
  1756. ;    btst    #NRB_WAIT_REPLY,nr_Flags+3(a3)
  1757. ;    beq.s    .D
  1758. ;    lea    NotifyPort(a5),a0
  1759. ;    CALL    WaitPort
  1760. ;    bsr    GetNotify
  1761. .D    rts
  1762.  
  1763. * Handle replies of Notify messages
  1764. GetNotify:
  1765. .A    lea    NotifyPort(a5),a0
  1766.     CALL    GetMsg
  1767.     tst.l    d0
  1768.     beq.s    .E
  1769.     move.l    d0,a1
  1770.     DBUG1    txgnoti,a1
  1771.     move.l    nm_NReq(a1),a0
  1772.     subq.l    #1,nr_MsgCount(a0)
  1773.     moveq    #NotifyMessage_SIZEOF,d0
  1774.     bsr    FreeMem
  1775.     bra.s    .A
  1776. .E    rts
  1777.  
  1778. *******************************************************
  1779.  
  1780. *******************************************************
  1781.  
  1782. * Following there are support subroutines for creating and deleting
  1783. * objects and Locks.
  1784.  
  1785. * Create a new file/dir
  1786. * ENTRY: a2=name, a3=parent dir, d2=data size
  1787. * EXIT:  d1=offset of data, d0=new file, Z-flag for success
  1788. CreateNewObject:
  1789.     move.w    #ERROR_DISK_FULL,dp_Res2+2(a4)
  1790. CreateNewObj:        ;label used by SearchPath and CalcFullName
  1791.     movem.l    d3/a2-a3,-(sp)
  1792.     move.l    a2,a0
  1793.     moveq    #myf_Name,d3
  1794. .D    addq.l    #1,d3
  1795.     tst.b    (a0)+
  1796.     bne.s    .D
  1797.     addq.l    #1,d3
  1798.     bclr    #0,d3
  1799.     move.l    d3,d0
  1800.     add.l    d2,d0
  1801.     bsr    AllocMem
  1802.     beq.s    .fail
  1803.     move.l    d0,a1
  1804.     lea    myf_First(a3),a0
  1805. .C    move.l    (a0),d0
  1806.     beq.s    .A
  1807.     move.l    d0,a0
  1808.     bra.s    .C
  1809. .A    move.l    a1,(a0)
  1810.     clr.l    myf_Link(a1)
  1811.     move.l    a3,myf_Parent(a1)
  1812.     move.l    d2,myf_Size(a1)
  1813.     add.l    d2,FileSize(a5)
  1814.     move.b    #$80,myf_Type(a1)
  1815.     move.b    d3,myf_DataOffs(a1)
  1816.     clr.b    myf_Locks(a1)
  1817.     lea    myf_Name(a1),a0
  1818. .E    move.b    (a2)+,(a0)+
  1819.     bne.s    .E
  1820.     move.l    d3,d1
  1821.     move.l    a1,d0
  1822. .fail    IFD    DEBUG
  1823.     move.l    d0,-(sp)
  1824.     lea    myf_Name(a1),a2
  1825.     move.l    myf_Size(a1),d0
  1826.     DBUG3    txcreat,a2,a1,d0
  1827.     move.l    (sp)+,d0
  1828.     ENDC
  1829.     movem.l    (sp)+,d3/a2-a3
  1830.     rts
  1831.  
  1832. * Delete file/dir in a1, no pred. known
  1833. * ENTRY: a1=file
  1834. * EXIT:  d0=success, Z-flag
  1835. DeleteObj:
  1836.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1837.     move.l    myf_Parent(a1),a0
  1838.     move.l    myf_First(a0),d0
  1839.     sub.l    a0,a0
  1840. .C    move.l    a0,d1
  1841.     move.l    d0,a0
  1842.     tst.l    d0
  1843.     beq    DelErr
  1844.     move.l    myf_Link(a0),d0
  1845.     cmp.l    a1,a0
  1846.     bne.s    .C
  1847.  
  1848. * Delete file/dir in a1 with pred. known
  1849. * ENTRY: a1=file d1=pred.
  1850. DeleteObject:
  1851.     move.l    d2,-(sp)
  1852.     moveq    #0,d0
  1853.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1854.     tst.b    myf_Locks(a1)
  1855.     bne.s    .fail
  1856.     tst.b    myf_Type(a1)
  1857.     bmi.s    .C
  1858.     move.w    #ERROR_DIRECTORY_NOT_EMPTY,dp_Res2+2(a4)
  1859.     tst.l    myf_First(a1)        ;check if dir is empty
  1860.     bne.s    .fail
  1861. .C    move.l    myf_Link(a1),d2        ;rearrange links
  1862.     move.l    d1,a0
  1863.     tst.l    d1
  1864.     bne.s    .A
  1865.     move.w    #ERROR_OBJECT_WRONG_TYPE,dp_Res2+2(a4)
  1866.     move.l    myf_Parent(a1),d1
  1867.     beq.s    .fail            ;do not delete root
  1868.     move.l    d1,a0
  1869.     lea    myf_First-myf_Link(a0),a0
  1870. .A    move.l    d2,myf_Link(a0)
  1871.     DBUG1    txdel,a1
  1872.     lea    NotifyList(a5),a0
  1873.     bra.s    .D
  1874. .E    move.l    d0,a0
  1875.     cmp.l    myn_Key(a0),a1
  1876.     bne.s    .D
  1877.     clr.l    myn_Key(a0)        ;check notifications
  1878. .D    move.l    (a0),d0
  1879.     bne.s    .E
  1880.     moveq    #0,d0            ;free memory
  1881.     move.b    myf_DataOffs(a1),d0
  1882.     move.l    myf_Size(a1),d1
  1883.     add.l    d1,d0
  1884.     sub.l    d1,FileSize(a5)
  1885.     bsr    FreeMem
  1886.     moveq    #1,d0
  1887. .fail    move.l    (sp)+,d2
  1888. DelErr    tst.l    d0        ;label not used globally
  1889.     rts
  1890.  
  1891. * Create lock on file/dir given by name
  1892. * Must preserve a3
  1893. * ENTRY: d0=BPTR parent lock, a0=name (BSTR), d2=access mode
  1894. * EXIT:  d0=APTR lock, Z-flag
  1895. LocateObject:
  1896.     move.w    #ERROR_OBJECT_NOT_FOUND,dp_Res2+2(a4)
  1897.     move.l    d0,d3
  1898.     bsr    SearchObject
  1899.     bne.s    .A
  1900.     moveq    #ACCESS_READ,d0
  1901.     cmp.l    d0,d2
  1902.     bne.s    .C
  1903.     move.l    d3,d0
  1904.     bsr    CalcFullName
  1905.     bne.s    .A
  1906. .C    moveq    #0,d0
  1907.     bra    LOfail2
  1908. .A    move.l    d0,a2
  1909.     btst    #6,myf_Type(a2)        ;hidden ?
  1910.     bne.s    .C
  1911.  
  1912. * Create lock on file/dir given by key
  1913. * ENTRY: a2=file, d2=access mode
  1914. * EXIT:  d0=success, Z-flag
  1915. CreateLock:
  1916.     moveq    #0,d0
  1917.     move.w    #ERROR_OBJECT_IN_USE,dp_Res2+2(a4)
  1918.     lea    myf_Locks(a2),a0
  1919.     moveq    #ACCESS_WRITE,d1
  1920.     cmp.l    d1,d2
  1921.     bne.s    .A
  1922.     tst.b    (a0)
  1923.     bne.s    LOfail
  1924.     move.b    d1,(a0)
  1925.     bra.s    .C
  1926. .A    tst.b    (a0)
  1927.     bmi.s    LOfail
  1928.     addq.b    #1,(a0)
  1929. .C    move.w    #ERROR_NO_FREE_STORE,dp_Res2+2(a4)
  1930.     move.l    #myl_SIZEOF,d0
  1931.     bsr    AllocMem
  1932.     beq.s    LOfail
  1933.     move.l    d0,a0
  1934.     clr.l    myl_Link(a0)
  1935.     clr.l    myl_Pos(a0)
  1936.     clr.l    myl_Data(a0)
  1937.     clr.l    myl_Start(a0)
  1938.     clr.l    myl_Block(a0)
  1939.     clr.l    myl_BlockPos(a0)
  1940.     clr.l    myl_Size(a0)
  1941.     move.l    a2,myl_Key(a0)
  1942.     move.l    d2,myl_Access(a0)
  1943.     move.l    MyMsgPort(a5),myl_Task(a0)
  1944.     move.l    MyVolumeBPTR(a5),myl_Volume(a0)
  1945.     clr.b    myl_Mode(a0)
  1946.     addq.l    #1,NumLocks(a5)
  1947. LOfail    IFD    DEBUG
  1948.     move.l    d0,d1
  1949.     lsr.l    #2,d1
  1950.     lea    myf_Name(a2),a0
  1951.     DBUG3    txlock,a0,d1,d2
  1952.     ENDC
  1953. LOfail2    tst.l    d0
  1954.     rts
  1955.  
  1956. * Free lock in a1
  1957. * ENTRY: a1=lock (APTR)
  1958. FreeLock:
  1959. ;    move.w    #ERROR_UNLOCK_ERROR,dp_Res2+2(a4)
  1960.     IFD    DEBUG
  1961.     move.l    a1,d0
  1962.     lsr.l    #2,d0
  1963.     DBUG1    txulock,d0
  1964.     ENDC
  1965.     move.l    myl_Key(a1),a0
  1966.     tst.b    myf_Locks(a0)
  1967.     beq.s    .A
  1968.     bmi.s    .D
  1969.     subq.b    #1,myf_Locks(a0)
  1970.     bra.s    .A
  1971. .D    clr.b    myf_Locks(a0)
  1972. .A    move.l    #myl_SIZEOF,d0
  1973.     bsr    FreeMem
  1974.     subq.l    #1,NumLocks(a5)
  1975.     rts
  1976.  
  1977. *******************************************************
  1978.  
  1979. *******************************************************
  1980.  
  1981. * Support routines for lower level memory management
  1982.  
  1983. * ENTRY: d0=size
  1984. * EXIT:  d0=memory
  1985. AllocMem:
  1986.     add.l    d0,TotalSize(a5)
  1987.     move.l    MyMemPool(a5),d1
  1988.     beq.s    .A
  1989.     move.l    d1,a0
  1990.     CALL    AllocPooled
  1991.     bra.s    .C
  1992. .A    moveq    #1,d1
  1993.     CALL    AllocMem
  1994. .C    tst.l    d0
  1995.     rts
  1996.  
  1997. * ENTRY: d0=size, a1=address
  1998. FreeMem:
  1999.     sub.l    d0,TotalSize(a5)
  2000.     move.l    MyMemPool(a5),d1
  2001.     beq.s    .A
  2002.     move.l    d1,a0
  2003.     CALL    FreePooled
  2004.     rts
  2005. .A    CALL    FreeMem
  2006.     rts
  2007.  
  2008. * Copy BSTR in a0 to string in a1, d0=maxlength without 0
  2009. CopyBSTR2Char:
  2010.     add.l    a0,a0
  2011.     add.l    a0,a0
  2012.     moveq    #0,d1
  2013.     move.b    (a0)+,d1
  2014.     MIN    d0,d1,D
  2015.     bra.s    .C
  2016. .A    move.b    (a0)+,(a1)+
  2017. .C    dbra    d1,.A
  2018.     clr.b    (a1)
  2019.     rts
  2020.  
  2021. * Copy string in a0 to BSTR in a1, d0=maxlength without 0
  2022. * EXIT:  d0=BPTR
  2023. CopyChar2BSTR:
  2024.     moveq    #-1,d1
  2025.     addq.l    #1,a1
  2026. .A    addq.l    #1,d1
  2027.     cmp.l    d0,d1
  2028.     bhs.s    .C
  2029.     move.b    (a0)+,(a1)+
  2030.     bne.s    .A
  2031.     subq.l    #1,a1
  2032. .C    clr.b    (a1)
  2033.     sub.l    d1,a1
  2034.     subq.l    #1,a1
  2035.     move.b    d1,(a1)
  2036.     move.l    a1,d0
  2037.     lsr.l    #2,d0
  2038.     rts
  2039.  
  2040. CopyChar2Char:
  2041. * Copy string in a0 to string in a1, d0=maxlength without 0
  2042. .C    move.b    (a0)+,(a1)+
  2043.     beq.s    .A
  2044.     subq.l    #1,d0
  2045.     bne.s    .C
  2046. .A    rts
  2047.  
  2048.  
  2049. *******************************************************
  2050.  
  2051. *******************************************************
  2052.  
  2053. * Subroutines for path string handling following
  2054.  
  2055. * Same as SearchObject, but deletes hidden files
  2056. * ENTRY: a0=filename (BSTR), d0=lock on dir
  2057. * EXIT:  d0=ptr to file, Z-flag, d1=previous file, TempPath=name
  2058. DelSearchObject
  2059.     bsr    SearchObject
  2060.     beq.s    .A
  2061.     move.l    d0,a1
  2062.     btst    #6,myf_Type(a1)
  2063.     beq.s    .A
  2064.     bsr    DeleteObject        ;delete hidden file
  2065.     moveq    #0,d0
  2066. .A    tst.l    d0
  2067.     rts
  2068.  
  2069. * Same as SearchPath, but creates the path if not existent
  2070. * ENTRY: TempPath=dirname, d0=lock on dir
  2071. * EXIT:  d0=ptr to file, Z-flag, d1=previous file
  2072. CreatePath:
  2073.     moveq    #1,d1
  2074.     bra.s    SearchP
  2075.  
  2076. * Look for object with path
  2077. * ENTRY: a0=filename (BSTR), d0=lock on dir
  2078. * EXIT:  d0=ptr to file, Z-flag, d1=previous file, TempPath=name
  2079. SearchObject:
  2080.     move.l    d0,-(sp)
  2081.     lea    TempPath(a5),a1
  2082.     moveq    #MAXPATH-1,d0
  2083.     bsr    CopyBSTR2Char
  2084.     move.l    (sp)+,d0
  2085.  
  2086. * Same as SearchObject, but name is already copied to TempPath
  2087. * ENTRY: TempPath=dirname, d0=lock on dir
  2088. * EXIT:  d0=ptr to file, Z-flag, d1=previous file
  2089. SearchPath:
  2090.     moveq    #0,d1
  2091. SearchP    movem.l    d2-d7/a2-a4,-(sp)    ;label not used globally
  2092.     move.l    d1,d7
  2093.     lea    RootDir(a5),a1
  2094.     lea    TempPath(a5),a0
  2095. .A    cmp.b    #":",(a0)+        ;skip volume name
  2096.     beq.s    .E
  2097.     tst.b    -1(a0)
  2098.     bne.s    .A
  2099.     lea    TempPath(a5),a0
  2100. .D    lsl.l    #2,d0            ;use root or locked dir
  2101.     beq.s    .E
  2102.     move.l    d0,a2
  2103.     move.l    myl_Key(a2),a1        ;dir represented by lock
  2104. .E
  2105. * label not used
  2106. expand    IFD    EXPAND
  2107.     tst.b    StupExpand(a5)        ;expand env:appname.prefs to
  2108.     beq    .A
  2109.     tst.l    myf_Parent(a1)        ;env:appname/appname.prefs
  2110.     bne    .A            ;not in rootdir ?
  2111.     move.l    a0,a4
  2112.     sub.l    a2,a2
  2113. .C    move.b    (a4)+,d0
  2114.     beq.s    .D
  2115.     cmp.b    #"/",d0            ;check for "/"
  2116.     beq    .A
  2117.     cmp.b    #".",d0
  2118.     bne.s    .C
  2119.     move.l    a4,a2            ;remember "."
  2120.     bra.s    .C
  2121. .D    move.l    a2,d0
  2122.     beq.s    .A
  2123.     sub.l    a0,d0
  2124.     lea    TempPath(a5),a3
  2125.     sub.l    a3,a4
  2126.     add.l    a4,d0
  2127.     cmp.l    #MAXPATH-1,d0
  2128.     bhs.s    .A
  2129.     move.l    a2,a4
  2130.     lea    prefstx(pc),a3        ;ends in ".prefs" ?
  2131. .cmp1    move.b    (a4)+,d0
  2132.     cmp.b    (a3)+,d0
  2133.     bne.s    .F
  2134.     tst.b    d0
  2135.     bne.s    .cmp1
  2136.     bra.s    .G
  2137. .F    move.l    a2,a4
  2138.     lea    configtx(pc),a3        ;ends in ".config" ?
  2139. .cmp2    move.b    (a4)+,d0
  2140.     cmp.b    (a3)+,d0
  2141.     bne.s    .A
  2142.     tst.b    d0
  2143.     bne.s    .cmp2
  2144.  
  2145. .G    tst.b    (a4)+
  2146.     bne.s    .G
  2147.     move.l    a4,a3
  2148.     sub.l    a0,a3
  2149.     add.l    a2,a3
  2150.     move.l    a4,d0
  2151.     sub.l    a0,d0
  2152.     bra.s    .I
  2153. .H    move.b    -(a4),-(a3)
  2154. .I    dbra    d0,.H
  2155.     move.b    #"/",-1(a2)
  2156.     DBUG1    txexp,a0
  2157.  
  2158. ;    move.b    #"/",-1(a2)        ;insert "/" instead of "."
  2159. ;    move.l    a0,a3
  2160. ;.H    move.b    (a3)+,d0        ;copy first part of filename
  2161. ;    move.b    d0,(a2)+
  2162. ;    cmp.b    #"/",d0
  2163. ;    bne.s    .H
  2164. ;    move.b    #".",-1(a2)        ;append ".prefs"
  2165. ;    lea    prefstx(pc),a3
  2166. ;.I    move.b    (a3)+,(a2)+
  2167. ;    bne.s    .I
  2168. ;    DBUG1    txexp,a0
  2169. .A    ENDC
  2170. * end of expand
  2171.  
  2172. * label not used
  2173. * ENTRY: a0=Name, a1=parent dir; mind SP !
  2174. * EXIT:  d0=ptr to file, Z-flag, d1=previous file
  2175. SearchName:
  2176. .A    moveq    #0,d0
  2177. .D    cmp.b    #"/",(a0)        ;parent dir when starting with /
  2178.     bne.s    .H
  2179.     move.l    myf_Parent(a1),d2
  2180.     beq.s    .fail
  2181.     move.l    d2,a1
  2182.     addq.l    #1,a0
  2183.     bra.s    .D
  2184. .H    tst.b    (a0)            ;check for empty string
  2185.     beq.s    .G
  2186.     move.l    a0,a4
  2187.     moveq    #0,d3
  2188. .C    addq.l    #1,d3            ;look for / or end
  2189.     tst.b    (a4)
  2190.     beq.s    .E
  2191.     cmp.b    #":",(a4)
  2192.     beq.s    .fail
  2193.     cmp.b    #"/",(a4)+
  2194.     bne.s    .C
  2195. .E    move.b    myf_Type(a1),d2
  2196.     bmi.s    .fail
  2197.     btst    #6,d2
  2198.     beq.s    .J
  2199.     tst.l    d7            ;check for CreatePath
  2200.     beq.s    .fail
  2201.     clr.b    myf_Type(a1)        ;convert hidden to dir
  2202. .J    move.l    a1,d2
  2203.     bsr    SearchEntry        ;search in dir
  2204.     bne.s    .F
  2205.     tst.l    d7            ;check for CreatePath
  2206.     beq.s    .G
  2207.     movem.l    d1-d3/a0/a2-a4,-(sp)
  2208.     move.l    d2,a3
  2209.     move.l    a0,a2
  2210.     move.l    a0,a4
  2211.     subq.l    #1,d3
  2212.     add.l    d3,a4
  2213.     move.b    (a4),d3
  2214.     clr.b    (a4)
  2215.     moveq    #0,d2
  2216.     bsr    CreateNewObj        ;create new dir
  2217.     move.b    d3,(a4)
  2218.     move.l    d0,a1
  2219.     movem.l    (sp)+,d1-d3/a0/a2-a4
  2220.     tst.l    d0
  2221.     beq.s    .G
  2222.     clr.b    myf_Type(a1)
  2223. .F    move.l    a4,a0
  2224.     bra.s    .A            ;continue looking for / or end
  2225. .G    move.l    a1,d0
  2226. .fail    IFD    DEBUG
  2227.     lea    TempPath(a5),a0
  2228.     moveq    #0,d2
  2229.     tst.l    d0
  2230.     beq.s    .I
  2231.     move.b    myf_Type(a1),d2
  2232. .I    DBUG3    txfnd,a0,d0,d2
  2233.     ENDC
  2234.     movem.l    (sp)+,d2-d7/a2-a4
  2235.     tst.l    d0
  2236.     rts
  2237.  
  2238. * Look for object in dir
  2239. * ENTRY: a0=file/dir name, a1=ptr to dir, d3=length of name
  2240. * EXIT:  a1=ptr to file or 0, Z-flag
  2241. SearchEntry:
  2242.     moveq    #0,d5
  2243.     moveq    #0,d6
  2244.     move.l    myf_First(a1),d0
  2245.     sub.l    a1,a1
  2246. .C    move.l    a1,d1
  2247.     move.l    d0,a1
  2248.     tst.l    d0
  2249.     beq.s    .fail
  2250.     move.l    myf_Link(a1),d0
  2251.     lea    myf_Name(a1),a2
  2252.     move.l    a0,a3
  2253.     move.l    d3,d4
  2254.     bra.s    .E
  2255. .A    move.b    (a2)+,d5
  2256.     move.b    CharTable(a5,d5.l),d5
  2257.     move.b    (a3)+,d6
  2258.     move.b    CharTable(a5,d6.l),d6
  2259.     cmp.b    d5,d6
  2260.     bne.s    .C
  2261. .E    subq.l    #1,d4
  2262.     bne.s    .A
  2263.     tst.b    (a2)
  2264.     bne.s    .C
  2265.     IFD    DEBUG
  2266.     lea    myf_Name(a1),a3
  2267.     DBUG1    txentry,a3
  2268.     ENDC
  2269. .fail    move.l    a1,d0
  2270.     rts
  2271.  
  2272. * Splits path with file into path=TempPath and file=TempName
  2273. * ENRTY: TempPath=file with path
  2274. * EXIT:  TempPath=path, TempName=file
  2275. SplitPath
  2276.     move.l    a2,-(sp)
  2277.     lea    TempPath(a5),a0
  2278.     move.l    a0,a1
  2279. .A    tst.b    (a0)+
  2280.     bne.s    .A
  2281. .D    cmp.b    #"/",-(a0)
  2282.     beq.s    .C
  2283.     cmp.b    #":",(a0)
  2284.     beq.s    .C
  2285.     cmp.l    a0,a1
  2286.     bne.s    .D
  2287.     move.l    a0,a1
  2288.     bra.s    .G
  2289. .C    move.l    a0,a1
  2290.     addq.l    #1,a1
  2291. .G    lea    TempName(a5),a2
  2292. .E    move.b    (a1)+,(a2)+
  2293.     bne.s    .E
  2294.     cmp.b    #":",(a0)
  2295.     bne.s    .F
  2296.     addq.l    #1,a0
  2297. .F    clr.b    (a0)
  2298.     move.l    (sp)+,a2
  2299.     IFD    DEBUG
  2300.     lea    TempPath(a5),a0
  2301.     lea    TempName(a5),a1
  2302.     DBUG2    txsplit,a0,a1
  2303.     ENDC
  2304.     rts
  2305.  
  2306. * Evaluate full path name of object
  2307. * Only used by CalcFullName
  2308. * ENTRY: a1=object
  2309. * EXIT:  a0=full name (root name not included) in TempPath
  2310. GetFullName:
  2311.     move.l    d2,-(sp)
  2312.     lea    TempPath+MAXPATH+MAXNAME-1(a5),a0
  2313.     clr.b    (a0)
  2314.     move.w    #MAXPATH+MAXNAME-1,d2
  2315. .A    move.l    myf_Parent(a1),d0
  2316.     beq.s    .ok
  2317.     lea    myf_Name(a1),a1
  2318.     moveq    #-1,d1
  2319. .C    addq.l    #1,d1
  2320.     tst.b    (a1)+
  2321.     bne.s    .C
  2322.     subq.l    #1,a1
  2323.     sub.w    d1,d2
  2324.     bmi.s    .ok
  2325.     tst.b    (a0)
  2326.     beq.s    .D
  2327.     move.b    #"/",-(a0)
  2328.     subq.w    #1,d2
  2329.     bra.s    .D
  2330. .E    move.b    -(a1),-(a0)
  2331. .D    dbra    d1,.E
  2332.     move.l    d0,a1
  2333.     bra.s    .A
  2334. .ok    move.l    (sp)+,d2
  2335.     rts
  2336.  
  2337. * Create dir and copy file from ENVARC: if possible
  2338. * Only used by LocateObject and UpNoti
  2339. * ENTRY: TempPath=name, d0=BPTR parent lock
  2340. * EXIT: d0=new file
  2341. CalcFullName:
  2342.     movem.l    d2-d6/a2-a4,-(sp)
  2343.     moveq    #0,d4            ;d4=return code
  2344.     tst.b    WriteProtected(a5)
  2345.     bne    .fail
  2346.     tst.l    Copyfrom(a5)
  2347.     beq    .fail
  2348.     bsr    CreatePath
  2349.     beq    .fail
  2350.     move.l    d0,a1
  2351.     move.l    d0,a2
  2352.     move.b    #$40,myf_Type(a1)    ;a2=new hidden file
  2353.     bsr    GetFullName
  2354.     DBUG1    txfull,a0
  2355.     lea    TempPath(a5),a1
  2356.     moveq    #MAXPATH-2,d0
  2357.     bsr    CopyChar2BSTR
  2358.     move.l    d0,d5            ;d5=BSTR full name
  2359.  
  2360.     move.l    #fib_SIZEOF+fh_SIZEOF,d0
  2361.     bsr    AllocMem
  2362.     beq    .fail
  2363.     move.l    d0,a3            ;a3=File info block
  2364.     lea    fib_SIZEOF(a3),a4    ;a4=file handle
  2365.  
  2366.     move.l    Copyfrom(a5),a0
  2367.     move.l    dol_Lock(a0),d1
  2368.     move.l    dol_List(a0),d6    
  2369.     bra.s    .D
  2370. .C    tst.l    d6
  2371.     beq    .fail2
  2372.     move.l    d6,a0
  2373.     move.l    (a0),d6        ;al_Next
  2374.     move.l    4(a0),d1    ;al_Lock
  2375. .D    move.l    d1,CopyfromLock(a5)
  2376.     move.l    d1,a0
  2377.     add.l    a0,a0
  2378.     add.l    a0,a0
  2379.     move.l    fl_Task(a0),CopyfromPort(a5)
  2380.     move.l    d5,d2
  2381.     moveq    #ACCESS_READ,d3
  2382.     moveq    #ACTION_LOCATE_OBJECT,d0
  2383.     bsr    DoPacket
  2384.     beq    .C
  2385.  
  2386.     move.l    d0,d3            ;d3=lock on file
  2387.     move.l    d3,d1
  2388.     move.l    a3,d2
  2389.     lsr.l    #2,d2
  2390.     moveq    #ACTION_EXAMINE_OBJECT,d0
  2391.     bsr    DoPacket
  2392.     move.l    d0,-(sp)
  2393.     move.l    d3,d1
  2394.     moveq    #ACTION_FREE_LOCK,d0
  2395.     bsr    DoPacket
  2396.     move.l    (sp)+,d0
  2397.     beq.s    .fail2
  2398.     tst.l    fib_DirEntryType(a3)
  2399.     bmi.s    .A
  2400.     clr.b    myf_Type(a2)        ;turn hidden into dir
  2401.     move.l    a2,d4
  2402.     bra.s    .fail2
  2403.  
  2404. .A    move.l    a4,d1
  2405.     lsr.l    #2,d1
  2406.     move.l    CopyfromLock(a5),d2
  2407.     move.l    d5,d3
  2408.     move.l    #ACTION_FINDINPUT,d0
  2409.     bsr    DoPacket
  2410.     beq.s    .fail2
  2411.     movem.l    a2/a3,-(sp)
  2412.     move.l    fib_Size(a3),d2
  2413.     move.l    myf_Parent(a2),a3
  2414.     lea    myf_Name(a2),a2
  2415.     bsr    CreateNewObject
  2416.     movem.l    (sp)+,a2/a3
  2417.     beq.s    .fail3
  2418.     move.l    d0,d2
  2419.     add.l    d1,d2
  2420.     move.l    a2,a1
  2421.     move.l    d0,a2
  2422.     move.b    #$a0,myf_Type(a2)
  2423.     bsr    DeleteObj
  2424.     beq.s    .fail3
  2425.     move.l    fh_Arg1(a4),a4
  2426.     move.l    a4,d1
  2427.     move.l    fib_Size(a3),d3
  2428.     moveq    #ACTION_READ,d0
  2429.     bsr    DoPacket
  2430.     bsr    UpdateNotify
  2431. .fail3    move.l    a4,d1
  2432.     move.l    #ACTION_END,d0
  2433.     bsr    DoPacket
  2434.     move.l    a2,d4
  2435. .fail2    move.l    a3,a1
  2436.     move.l    #fib_SIZEOF+fh_SIZEOF,d0
  2437.     bsr    FreeMem
  2438. .fail    move.l    d4,d0
  2439.     movem.l    (sp)+,d2-d6/a2-a4
  2440.     rts
  2441.  
  2442. *******************************************************
  2443.  
  2444. *******************************************************
  2445.  
  2446. * Debug output support subroutines and strings following
  2447.  
  2448.     IFD    DEBUG
  2449.  
  2450. * Output one character
  2451. RawHook    move.l    a6,-(sp)
  2452.     move.l    4.w,a6
  2453.     jsr    _LVORawPutChar(a6)
  2454.     move.l    (sp)+,a6
  2455.     rts
  2456.  
  2457. * Wait for CTRL-C signal
  2458. wait_c:
  2459.     movem.l    d0-d1/a0-a1,-(sp)
  2460.     moveq    #0,d0
  2461.     moveq    #0,d1
  2462.     bset    #12,d1
  2463.     jsr    _LVOSetSignal(a6)
  2464.     moveq    #0,d0
  2465.     bset    #12,d0
  2466.     jsr    _LVOWait(a6)    ;wait for CTRL-C
  2467.     movem.l    (sp)+,d0-d1/a0-a1
  2468.     rts
  2469.  
  2470.     IFD    VERBOSE
  2471. txstart    dc.b    "Handler started, A5=$%lx.",10,0
  2472. txend    dc.b    "Handler ended, FileSize=%ld, TotalSize=%ld, Locks=%ld..",10,0
  2473. txcopy    dc.b    "Copyfrom=$%lx.",10,0
  2474. txpack    dc.b    "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
  2475. txres    dc.b    "Result1=$%lx, Result2=%ld.",10,0
  2476. txpkt    dc.b    "  Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
  2477. txerr1    dc.b    "  %ld: Unknown Action.",10,0
  2478.  
  2479. txopeno    dc.b    "  Oldopen lock=$%lx.",10,0
  2480. txopenn    dc.b    "  Newopen lock=$%lx.",10,0
  2481. txcreat    dc.b    "  Created file %s=$%lx size=%ld.",10,0
  2482. txread    dc.b    "  Read %ld of %ld bytes, pos=%ld.",10,0
  2483. txwrite    dc.b    "  Wrote %ld bytes, pos=%ld, size=%ld.",10,0
  2484. txwins    dc.b    "  Inserted %ld bytes at %ld.",10,0
  2485. txchng    dc.b    "  Changed mode, pos=%ld, size=%ld.",10,0
  2486. txseek    dc.b    "  Seeked, filepos=%ld.",10,0
  2487. txdel    dc.b    "  Deleted $%lx.",10,0
  2488.  
  2489. txlock    dc.b    "  Locked %s=$%lx mode %ld.",10,0
  2490. txulock    dc.b    "  Unlocked $%lx.",10,0
  2491. txexam    dc.b    "  Examined file=$%lx.",10,0
  2492. txexnx    dc.b    "  Examined next file=$%lx.",10,0
  2493. txfnd    dc.b    "    Found %s=$%lx type=$%lx.",10,0
  2494. txentry    dc.b    "    Found entry %s.",10,0
  2495. txsplit    dc.b    "    Splitted ->%s,%s.",10,0
  2496. txfull    dc.b    "    Full name: %s.",10,0
  2497. txexp    dc.b    "    Expanded path to %s.",10,0
  2498.  
  2499. txanoti    dc.b    "  Added noti $%lx->$%lx on %s key=$%lx.",10,0
  2500. txrnoti    dc.b    "  Removed noti $%lx->$%lx.",10,0
  2501. txcnoti    dc.b    "  Checking noti on %s.",10,0
  2502. txunoti    dc.b    "    Updated noti on %s key=$%lx.",10,0
  2503. txsnoti    dc.b    "    Sent signal to %s for %s.",10,0
  2504. txmnoti    dc.b    "    Sent message $%lx to %s for %s.",10,0
  2505. txgnoti    dc.b    "    Got message $%lx.",10,0
  2506.     ENDC
  2507.  
  2508.     IFND    VERBOSE
  2509. txstart    dc.b    "Handler started, A5=$%lx.",10,0
  2510. txend    dc.b    "Handler ended, FileSize=%ld, TotalSize=%ld, Locks=%ld.",10,0
  2511. txcopy    dc.b    "Copyfrom=$%lx.",10,0
  2512. txpack    dc.b    "Type=%ld Arg1=$%lx Arg2=$%lx Arg3=$%lx, Task=%s.",10,0
  2513. txres    dc.b    "Result1=$%lx, Result2=%ld.",10,0
  2514. txpkt    dc.b    0;"  Packet=$%lx, type=%ld, res=$%lx, err=%ld.",10,0
  2515. txerr1    dc.b    "  %ld: Unknown Action.",10,0
  2516. txargs    dc.b    "Args: $%lx, $%lx, $%lx, $%lx.",10,0
  2517.  
  2518. txopeno    dc.b    "  Oldopen lock=$%lx.",10,0
  2519. txopenn    dc.b    "  Newopen lock=$%lx.",10,0
  2520. txcreat    dc.b    "  Created file %s=$%lx size=%ld.",10,0
  2521. txread    dc.b    0;"  Read %ld of %ld bytes, pos=%ld.",10,0
  2522. txwrite    dc.b    0;"  Wrote %ld bytes, pos=%ld, size=%ld.",10,0
  2523. txwins    dc.b    0;"  Inserted %ld bytes at %ld.",10,0
  2524. txchng    dc.b    0;"  Changed mode, file=$%lx, pos=%ld, size=%ld.",10,0
  2525. txsize    dc.b    0;"  Changed size, file=$%lx, oldsize=%ld, newsize=%ld.",10,0
  2526. txseek    dc.b    0;"  Seeked, filepos=%ld.",10,0
  2527. txdel    dc.b    "  Deleted $%lx.",10,0
  2528.  
  2529. txlock    dc.b    0;"  Locked %s=$%lx mode %ld.",10,0
  2530. txulock    dc.b    0;"  Unlocked $%lx.",10,0
  2531. txexam    dc.b    0;"  Examined file=$%lx.",10,0
  2532. txexan    dc.b    0;"    Examined %s.",10,0
  2533. txexnx    dc.b    0;"  Examined next file=$%lx.",10,0
  2534. txfnd    dc.b    0;"    Found %s=$%lx type=$%lx.",10,0
  2535. txentry    dc.b    0;"    Found entry %s.",10,0
  2536. txsplit    dc.b    0;"    Splitted ->%s,%s.",10,0
  2537. txfull    dc.b    0;"    Full name: %s.",10,0
  2538. txexp    dc.b    "    Expanded path to %s.",10,0
  2539.  
  2540. txanoti    dc.b    "  Added noti $%lx->$%lx on %s key=$%lx.",10,0
  2541. txrnoti    dc.b    "  Removed noti $%lx->$%lx.",10,0
  2542. txcnoti    dc.b    0;"  Checking noti on %s.",10,0
  2543. txunoti    dc.b    0;"    Updated noti on %s key=$%lx.",10,0
  2544. txsnoti    dc.b    0;"    Sent signal to %s for %s.",10,0
  2545. txmnoti    dc.b    0;"    Sent message $%lx to %s for %s.",10,0
  2546. txgnoti    dc.b    0;"    Got message $%lx.",10,0
  2547.     ENDC
  2548.  
  2549.     ENDC
  2550.  
  2551. *******************************************************
  2552.  
  2553. * Alles hat ein Ende ...  ;-)
  2554.  
  2555.     END
  2556.  
  2557.